Secteur Tertiaire Informatique Filière étude - développement. Activité Développer des composants d’interface Etape développer des composants d'accès aux données Séance Alimenter et extraire des données Utiliser JDBC avec MySql Accueil Apprentissage Période en entreprise Evaluation CODE BARRE SOMMAIRE I Qu’est–ce que JDBC?............................................................................................................ 4 II I.1 I.2 I.3 Introduction........................................................................................................................................... 4 Technologies ......................................................................................................................................... 5 Le package java.sql ............................................................................................................................. 6 La connexion aux bases de données. ......................................................................... 7 II.1 Etablissement d’un pont JDBC-ODBC vers la base de données ..... Erreur ! Signet non défini. II.2 Chargement de la classe du Driver désiré ................................................................................... 7 II.3 Etablissement de la connexion ....................................................................................................... 8 III III.1 III.2 III.3 Passage d'une requête et exploitation des résultats .......................................... 10 Requêtes directes. ........................................................................................................................ 10 Exploitation des résultats. .......................................................................................................... 11 Les requêtes pré compilées ( ou paramétrées)................................................................... 14 3 I QU’EST–CE QUE JDBC? I.1 Introduction JDBC (Java DataBase Connectivity) est l’API java développée par Sun MicroSystems pour se connecter à des bases de données hétérogènes via une API. JDBC est conçue pour que le développeur puisse se concentrer au maximum sur son application, et perde le moins d’énergie possible pour traiter des problèmes techniques de liens avec la base de données. JDBC à trois rôles : · Se connecter à une base de données avec l’interface adéquate (driver ou pilote). · Envoyer des requêtes SQL. · Exploiter les résultats des requêtes. Avec une interface JDBC, nous avons une solution objet, simple, en pur Java, à condition de disposer du driver JDBC correspondant à votre base de données. Il existe des drivers pour Oracle, Sybase, Informix, DB2, MySQL, ainsi que des drivers "génériques" comme ODBC pour Windows. ODBC (Open Database Connectivity) est une API Microsoft présente sur les platesformes Windows qui permet à des applications de se connecter à plusieurs types de bases de données. Bien que les applications java puissent communiquer directement avec les bases de données via des drivers JDBC (appelés drivers propriétaires), elles peuvent également communiquer via les drivers ODBC si vous disposez d'un driver de pont JDBC-ODBC sur la machine cliente. Le driver JDBC propriétaire ne nécessite pas de configuration de la machine cliente, mais vous devrez implémenter les classes propriétaires (comme les classes classe12.jar d’Oracle). Le driver ODBC nécessite un paramétrage particulier sur la machine cliente (création d'une source de données ODBC) Suivant l'architecture choisie (Driver propriétaire ou pont JDBC-ODBC), le paramétrage de la connexion sera différent. AFPA 2014 - Java et JDBC page 4/15 I.2 Technologies Technologie 2/3 ou client-serveur. jdbc appli java Base de données client serveur Technologie 3/3 ou serveur d’application et serveur de base de données présentation appli java Client html ou applet jdbc Serveur Base de données Serveur de base de données L’avantage de la technologie 3/3 est de permettre de sérier les problèmes. Cela permet encore de décharger le client et de le banaliser ( explorateur internet ), et d’améliorer les performances globales du système ( client plus réduit, moins d’informations sur les lignes, … ). JDBC est conforme au standard SQL. Voici un schéma du fonctionnement de java/JDBC : Application JAVA API JDBC JDBC Manager API JDBC Driver Pont JDBC-ODBC Pilote JDBC propriétaire Pilote ODBC SGBD AFPA 2014 - Java et JDBC page 5/15 I.3 Le package java.sql Tous les objets et les méthodes relatifs aux bases de données sont présents dans le package java.sql, il est donc indispensable d'importer java.sql.* dans tout programme se servant de la technologie JDBC. Les principales interfaces de java.sql sont : java.sql.DriverManager : Elle prend en charge le chargement des pilotes et permet de créer de nouvelles connexions à des bases de données. java.sql.Connection : Elle représente une connexion à une base de données java.sql.Statement : C'est une classe que l'application emploie pour transmettre des instructions à la base, elle représente une requête SQL. java.sql.ResultSet : Cette classe symbolise un ensemble de résultats dans la base de données et autorise l'accès aux résultats d'une requête enregistrement par enregistrement java.sql.PreparedStatement: Interface qui permet d’exécuter des requêtes paramétrées java.sql.CallableStatement: Interface qui permet l’appel de procédures stockées. AFPA 2014 - Java et JDBC page 6/15 II LA CONNEXION AUX BASES DE DONNEES. La classe DriverManager est le gestionnaire des drivers permettant à l’utilisateur l’accès aux bases de données. Quel que soit le gestionnaire de Base de Données considéré, les étapes pour manipuler les données d'une base de données sont identiques : - Charger le pilote. Ouvrir une connexion à la base de données. Préparer la requête SQL Exécuter la requête Récupérer les résultats Fermer la connexion à la base de données II.1 Chargement de la classe du Driver désiré Pour se connecter à une base de données il est essentiel de charger dans un premier temps le pilote de la base de données à laquelle on désire se connecter grâce à un appel au DriverManager (gestionnaire de pilotes) : Class.forName("nom.de.la.classe"); Cette instruction charge le pilote et crée une instance de cette classe. Dans le cas du driver propriétaire MySql, le pilote à charger est : "com.mysql.jdbc.Driver" note : Vous devrez importer les packages mysql-connector de mysql-connector-java-5.1.30bin.jar dans votre projet. Exemple : Driver JDBC MySql import java.sql.*; try { Class.forName("com.mysql.jdbc.Driver ") ; // pour charger le driver Jdbc } catch ( Exception e) { … } AFPA 2014 - Java et JDBC page 7/15 II.2 Etablissement de la connexion Une fois le driver chargé, vous pouvez alors établir une connexion à la base de données. Pour ce faire, on utilise la méthode getConnection() sur la classe DriverManager qui prend un URL en argument. Exemple : Demande d'une connexion à la base avec le nom d'user et son mot de passe pswd Connection con = null; try{ con = DriverManager.getConnection(url,"user","pswd"); } catch(Exception e) { … } L'url est une chaîne de caractères qui spécifié : - l'utilisation de JDBC le driver ou le type du SGBDR l'identification de la base de données. JDBC : Si vous utilisez le driver propriétaire MySql, la syntaxe est : String url = " jdbc:mysql://localhost:3306/Salarie"; // Salarie étant le nom de la base de données ou xx.xx.xx.xx étant l'adresse IP de la machine SGBD ou le nom host de la machine 3306, le port par défaut pour MySql. Exemple de connexion à une base de données via le driver JDBC direct : import java.sql.*; // importation des classes jdbc public class Class1 { public static void main (String[] args) { try { // chargement de la classe du pilote Class.forName ("com.mysql.jdbc.Driver") } AFPA 2014 - Java et JDBC page 8/15 catch(Exception e) { e.printStackTrace (); } try { String url =" jdbc:mysql://localhost:3306/Salarie"; Connection con= DriverManager.getConnection(url,"user","pwd"); System.out.println ("ça marche "); } catch(Exception e) { System.out.println ("la connexion a échoué"); } } } AFPA 2014 - Java et JDBC page 9/15 III PASSAGE D'UNE REQUETE ET EXPLOITATION DES RESULTATS Ici nous allons passer une requête à la base de données et exploiter les éventuels résultats. Dès que nous avons récupéré une connexion, nous allons pouvoir passer des requêtes à la base. Nous allons pouvoir travailler de trois manières différentes : · · · Les requêtes directes à la base (Statement). Les requêtes préparées (PreparedStatement). Ce sont des requêtes, souvent paramétrées, qui sont précompilées par la base, ce qui accélère leur traitement. Nous utiliserons des requêtes préparées chaque fois qu'une requête doit être passées sur un grand ensemble de données. L'appel de procédures stockées. Nous verrons également comment exploiter les résultats des requêtes. III.1 Requêtes directes. Exemple de requête une fois que nous avons obtenu une connexion (con). Statement stm = con.createStatement(); // création d'un objet requête directe ResultSet Resultat; // création d'une variable qui référencera l'ensemble des résultats Resultat = stm.executeQuery("SELECT x,y,z FROM table"); // exécution de la requête // nous exploiterons plus loin les résultats int ret = stm.executeUpdate("DELETE …"); Il existe trois manières d'exécuter des requêtes SQL. · ExecuteQuery : c'est une interrogation qui produit un ensemble simple de lignes résultat ( SELECT ) · ExecuteUpdate : c'est la modification de l'état de la base (INSERT, UPDATE, DELETE, CREATE TABLE, DROP TABLE ). Le résultat est la modification de 1 ou plusieurs colonnes de 0 à plusieurs lignes de la table. Cela retourne le nombre de lignes modifiées ( pour les requêtes CREATE et DROP le résultat est toujours 0 ). · Execute : est utilisé pour l'appel aux procédures stockées. AFPA 2014 - Java et JDBC page 10/15 III.2 Exploitation des résultats. Un ResultSet contient en retour d'un executeQuery toutes les lignes qui satisfont les conditions. Reprenons notre code: ResultSet res = stm.executeQuery("SELECT CH1,CH2,CH3 FROM table"); // Exploitation du résultat de la requête while (res.next()) { int i = res.getInt("CH1"); String str = res.getString("CH2"); Float f = res.getFloat("CH3"); System.out.println("ligne = " + i + str + f ); } res.close(); // il est recommandé de fermer le resultset //même si le garbage collector fait le travail quand même. con.close(); // idem pour la connexion Le ResultSet à un curseur sur les lignes résultantes. Initialement ce curseur est positionné avant la première ligne. La méthode next() le positionne sur la ligne suivante. Pour lire la ligne nous utilisons les fonctions: · · getXXX( "nom-de-colonne"); ou XXX est le type de la donnée lue ( voir la classe ResultSet ) . getXXX(numcolonne); ou XXX est le type de la donnée lue ( voir la classe ResultSet ) et numcolonne est le numéro de la colonne concernée ( 1 pour la colonne la plus à gauche ). Les noms de colonne ne peuvent être utilisés que si ils figurent dans la requête SQL. Si deux colonnes ont le même nom, l'accès par le nom de colonne ne donne que la première des deux. Il est plus efficace de passer par le numéro de colonne, mais il est plus lisible de passer par le nom des colonnes (sauf dans le cas ou le nom est dupliqué ). Voici un exemple de traitement d'une requête SQL en direct sans résultat, et d'une requête SQL avec un ResultSet. AFPA 2014 - Java et JDBC page 11/15 // exemple de requête SQL sans résultat import java.sql.*; public class Class1 { public static void main (String[] args) { try { //Chargement de la classe du 'Driver' //pour établir la connexion JDBC Class.forName ("com.mysql.jdbc.Driver"); } catch(Exception e) { System.out.println ("le pilote n'a pu être chargé"); } try { //établissement de la connexion au lien JDBC String url ="jdbc:mysql://localhost:3306/Salarie"; Connection con= DriverManager.getConnection(url,"user","pwd"); //création d'un objet de la classe Statement qui permet //d'effectuer des requêtes liées à la connexion 'con' Statement stm=con.createStatement (); //appel de la méthode executeUpdate de la classe //Statement qui permet d'écrire dans une base stm.executeUpdate("INSERT INTO TABLEX VALUES(X,Y,Z)"); //il est recommandé de fermer l'objet Statement stm.close(); //et de fermer la connexion con.close (); } catch(Exception e) { //ceci permet d'écrire l'exception interceptée e.printStackTrace (); } } } AFPA 2014 - Java et JDBC page 12/15 // exemple de requête SQL avec un résultat import java .sql .*; public class Class1 { public static void main (String[] args) { try { //Chargement de la classe du 'Driver' //pour établir la connexion JDBC Class.forName ("com.mysql.jdbc.Driver"); } catch(Exception e) { System.out.println ("le pilote n'a pu être chargé"); } try { //établissement de la connexion au lien JDBC String url ="jdbc:mysql://localhost:3306/Salarie"; Connection con= DriverManager.getConnection(url,"user","pwd"); Statement stm=con.createStatement (); //executeQuery correspond à la demande d'exécution de la // requête. La variable result ( ResultSet ) est // l'ensemble des résultats renvoyés par la requête ResultSet result = stm.executeQuery ("SELECT * FROM TABLEX"); //next renvoie true lorsqu'il existe un enregistrement supplémentaire while(result.next()) { //conversion du résultat dans le bon type int X=result.getInt(1); String Y=result.getString(2); System.out.println ("X : " + X + " Y : " + Y); } //il est recommandé de fermer les objets Statement et Resultset stm.close(); result.close(); //et de fermer la connexion con.close (); } catch(Exception e) { //ceci permet d'écrire l'exception interceptée e.printStackTrace (); } } } AFPA 2014 - Java et JDBC page 13/15 III.3 Les requêtes pré compilées ( ou paramétrées). Les requêtes pré compilées sont des requêtes " à trous ", que le SGBD compile afin de préparer leur exécution. Cela permet d'accélérer leur traitement. La classe PreparedStatement représente ce type de requête. Une PreparedStatement contient une requête pré compilée. Elle a au moins un paramètre en entrée. Ce paramètre est représenté dans la requête par un point d'interrogation '?'. Avant l'exécution d'une PreparedStatement il faut appeler la fonction setXXX pour chacun de ces paramètres ( afin d'assigner des valeurs à tous les paramètres). Les PreparedStatements sont des requêtes exécutées un grand nombre de fois, qui sont pré compilées afin d'en optimiser le traitement. La classe PreparedStatement hérite de Statement, mais il ne faut pas utiliser les méthodes de la classe mère, mais toujours les méthodes de la classe fille. Exemple d'utilisation: // préparation de la requête PreparedStatement stm = con.prepareStatement("UPDATE table SET m=? WHERE x=?"); // affectation de valeurs aux paramètres de la requête stm.setString(1,"toto"); stm.setFloat(2,5.0); // exécution de la requête stm.executeUpdate(); Pour l'appel suivant nous pouvons redéfinir un ou plusieurs des paramètres, les paramètres non modifiés étant conservés. La fonction clearParameters() efface tous les paramètres. Le mode de fonctionnement par défaut est le mode autocommit. setNull() met un paramètre à null. setxxx () xxx représente le type Java. Dans le cas d'un SELECT le traitement du ResultSet retourné est le même que pour une requête directe. Il est à noter que les points d'interrogation de la PreparedStatement ne remplacent que des valeurs de champs de la base. Ils ne peuvent pas se substituer à des noms de colonne, ou de table; cela serait l'objet de la définition d'une nouvelle requête. Voici un exemple de traitement par une requête pré compilée: AFPA 2014 - Java et JDBC page 14/15 // exemple de requêtes paramétrées import java .sql .*; // importation des classes SQL public class Class1 { public static void main (String[] args) { try { //Chargement de la classe du 'Driver' //pour établir la connexion JDBC Class.forName ("com.mysql.jdbc.Driver"); } catch(Exception e) { System.out.println ("le pilote n'a pu être chargé"); } try { //établissement de la connexion au lien JDBC String url ="jdbc:mysql://localhost:3306/Salarie"; //Créer une requête prédéfinie sur la connexion con PreparedStatement stm = con.prepareStatement ( "SELECT * FROM TABLEX WHERE colZ=? "); //donner la valeur du paramètre pour l'exécution de la requête stm.setString (1,"Z" ); // la requête deviendra "SELECT * FROM TABLEX WHERE colZ='Z' //exécution de la requête (lecture de la base) ResultSet result =stm.executeQuery (); //affichage du résultat while(result.next()) { int X=result.getInt(1); String Y=result.getString(2); System.out.println ("X : " + X + " Y : " + Y); } // fermeture de la requête stm.close(); //Créer une requête prédéfinie avec deux paramètres stm = con.prepareStatement ("UPDATE TABLEX SET colX=? WHERE colZ=? "); //donner les valeurs manquant à la requête pour chacun //des deux paramètres de la requête paramétrée stm.setInt (1,10 ); stm.setString (2,"Z" ); // la requête deviendra UPDATE TABLEX SET colX=10 WHERE colZ='Z' //exécuter la requête stm.execute (); //fermeture de la requête stm.close (); // fermeture de la connexion con.close (); } catch(Exception e) AFPA 2014 - Java et JDBC page 15/15 Etablissement référent AFPA Grenoble le Pont de Claix AFPA St Brieuc Equipe de conception Jean Christophe Corre Patrice François Reproduction interdite Article L 122-4 du code de la propriété intellectuelle. «toute représentation ou reproduction intégrale ou partielle faite sans le consentement de l’auteur ou de ses ayants droits ou ayants cause est illicite. Il en est de même pour la traduction, l’adaptation ou la reproduction par un art ou un procédé quelconques.» Date de mise à jour jj/mm/aa afpa ã Date de dépôt légal mois année afpa / Direction de l’Ingénierie13 place du Générale de Gaulle / 93108 Montreuil Cedex association nationale pour la formation professionnelle des adultes Ministère des Affaires sociales du Travail et de la Solidarité