JDBC : **Java Database Connectivity** Une **bibliothèque** du JDK pour interagir avec une **base de données relationnelle**. Cette API générique permet de faire **des requêtes SQL** quel que soit le SGBD utilisé (ex. SQLite, PostgreSQL, MariaDb). Documentation Javadoc du package `java.sql` : https://docs.oracle.com/en/java/javase/25/docs/api/java.sql/java/sql/package-summary.html ## Driver ```mermaid flowchart TB app[Application Java] jdbc[API JDBC] driver[Driver JDBC] sqlite[SQLite] postgres[PostgreSQL] mariadb[MariaDB] app---jdbc jdbc---driver driver ---- sqlite driver ---- postgres driver ---- mariadb ``` ### Installation Ajouter la dépendance d'un driver JDBC à votre projet > [!example]- Driver SQlite > Maven > ```xml > <dependency> > <groupId>org.xerial</groupId> > <artifactId>sqlite-jdbc</artifactId> > <version>3.51.0.0</version> > </dependency> > ``` > > Gradle (kotlin) > ```kotlin > dependencies { > implementation("org.xerial:sqlite-jdbc:3.51.0.0") > } > ``` > [!example]- Driver MariaDB > Maven > ```xml > <dependency> > <groupId>org.mariadb.jdbc</groupId> > <artifactId>mariadb-java-client</artifactId> > <version>3.5.7</version> > </dependency> > ``` > > Gradle (kotlin) > ```kotlin > dependencies { > implementation("org.mariadb.jdbc:mariadb-java-client:3.5.7") > } > ``` > [!example]- Driver PostgreSQL > Maven > ```xml > <dependency> > <groupId>org.postgresql</groupId> > <artifactId>postgresql</artifactId> > <version>42.7.10</version> > </dependency> > ``` > > Gradle (kotlin) > ```kotlin > dependencies { > implementation("org.postgresql:postgresql:42.7.10") > } > ``` ## Interagir avec une base de données depuis Java 1. Se connecter à une base de données (via le driver) 2. Créer une ou des requêtes SQL 3. Exécuter les requêtes 4. Récupérer et traiter les données ### Chaine de connexion JDBC Une façon standardisée de codifier comment accéder à une base de données depuis JDBC. ```text "jdbc:mysql://mysql.db.server:3306/my_database" ^ ^ ^ ^ | | | | SGBD URL du serveur Port Base de données ``` ### Créer une connexion à l'aide du `DriverManager` ```java import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; ``` Création d'une connexion à une base de données avec user et mot de passe. ```java Connection connection = DriverManager.getConnection("jdbc:sqlite:test.db","user","password"); ``` Création d'une connexion à une base de données sans mot de passe. ```java Connection connection = DriverManager.getConnection(databaseUrl); ``` Exemple complet connexion à une base de données. ```java String databaseUrl= "jdbc:sqlite:databasename.db"; try (Connection connection = DriverManager.getConnection(databaseUrl); ) { // Faire des choses avec la connexion } catch (SQLException e) { System.err.println("Erreur lors de la connexion à la base de données : " + e.getMessage()); } ``` ### Exécuter une requête A partir d'une `Connection` **ouverte**. De façon simplifiée : ```java Statement stmt = connection.createStatement(); String query = "SELECT id, name FROM customer"; ResultSet rs = stmt.executeQuery (query) ; rs.close() // ResultSet est AutoCloseable stmt.close() // Statement est AutoCloseable connection.close(); // Connection est AutoCloseable ``` Les imports nécessaires ```java import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; ``` Exemple plus détaillé ```java try (Statement statement = connection.createStatement() ) { String query = """ SELECT id, name FROM customer """; try (ResultSet resultSet = statement.executeQuery(query) ) { while (resultSet.next()) { int id = resultSet.getInt("id"); String name = resultSet.getString("name"); // Faire quelque chose avec ces données } } } catch (SQLException e) { // Gérer l'erreur comme il se doit } ``` ### Correspondance des types Java et Sql ![[image-35.png|320x392]] ### Requêtes dynamiques et injection SQL > [!danger] Il ne faut pas écrire des requêtes dynamiques par concaténation de texte > ```java > String name = "Voldemort"; > String query = "SELECT id, name FROM customer WHERE name='" + name +"'"; > ``` Cela est une **faille de sécurité critique** qui rend votre application vulnérable aux **injections SQL**. En gros, vous permettez à un attaquant de contrôler votre base de données si vous n'assainissez pas vos requêtes SQL. JDBC propose un système de **requêtes préparées** pour assainir vos requêtes. #### Requêtes préparées Une requête préparée est une requête qui contient **des paramètres** à fournir pour son exécution Elle sert en général à effectuer des concaténations dans une requête SQL ```java String query = " SELECT * FROM employees INNER JOIN " + " offices ON employees.officeCode = offices.officeCode " + " WHERE offices.country =? " // 1 + " AND employees. lastName = ? "; // 2 try (PreparedStatement statement = connection.prepareStatement(query)) { statement.setString(1, "USA"); statement.setString(2, "Murphy"); ResultSet rs = statement.executeQuery(); // traiter les données } ``` ## À suivre [[Stream API]]