La technologie JDBC (Java DataBase Connectivity)
Transcription
La technologie JDBC (Java DataBase Connectivity)
APPLICATIONS JAVA JDBC (Java DataBase Connectivity) SQL (rappel) Java DataBase Connectivity IvMad - 2012 Architecture Java-JDBC-SGBD 2 Java DataBase Connectivity IvMad - 2012 3 Architecture Java-JDBC-SGBD • Les composants de la connexion avec un base de données relationnelle gérés par le Driver Manager Java DataBase Connectivity IvMad - 2012 JDBC - Java Database Connectivity • JDBC permet à un programme Java d'interagir • localement ou à distance • avec une base de données relationnelle • Fonctionne selon le principe client-serveur (connexion TCP/IP) • Un client : le programme Java • Un serveur : un SGBD (ex: MySQL, SQL Server, PostgreSQL) • Principe • le programme Java charge le pilote • le programme Java ouvre une connexion • le programme Java envoie des requêtes SQL • le programme Java récupère les résultats • le programme Java effectue des traitements des données ... • le programme Java ferme la connexion 4 Java DataBase Connectivity IvMad - 2012 5 JDBC - Java Database Connectivity • Connexion à une base de données • Une application Java doit mentionner l'URL de la base de données : String NomUrl = "jdbc:SousProtocole:SourceDeDonnées"; • Pour accéder à une source de données, il est nécessaire de disposer d'un pilote JDBC propre au modèle de la base de données. jdbc.NomDriver • Le driver doit être instancier et enregistre par une instruction spécifique : Pour utiliser le pilot JDBC-MySQL: Class.forName("com.mysql.jdbc.Driver"); • Le gestionnaire de la base de données correspondant à l'URL fournie lance une connexion à la base en utilisant le nom d'utilisateur et le mot de passe indiqués. Connection con = DriverManager.getConnection (Url, "Utilisateur", "MotDePasse"); Java DataBase Connectivity IvMad - 2012 JDBC - Java Database Connectivity • Les requêtes de sélection : • L'objet Connection créé va permettre d'interagir avec la base. Pour réaliser des requêtes de sélection, un objet de type Statement doit être généré. • Statement symbolise une instruction SQL. Statement requete = con.createStatement(); • Le résultat d'une requête est récupéré par un objet de type ResultSet et permet d'accéder aux données extraites grâce à la requête. ResultSet resultat = requete.executeQuery ("select * from etudiant"); • Après la requête, le "curseur" est positionné juste avant la première ligne du résultat, la méthode next() permet d'avancer d'enregistrements en enregistrements séquentiellement : resultat.next() • Pour récupérer les données dans chaque colonne, l'interface ResultSet propose plusieurs méthodes adaptées aux types des données récupérées : getString(NumCol), getInt(NumCol), getDate(NumCol) 6 Java DataBase Connectivity IvMad - 2012 7 JDBC - Java Database Connectivity • Les requêtes de mises à jour : • La mise à jour d'une base de données peut être effectuée par le biais d'une requête SQL de type UPDATE, INSERT ou DELETE à partir de la méthode executeUpdate("Requête") sur un objet Statement. • Le résultat renvoyé par l'exécution de la requête indiquera le nombre de lignes mises à jour dans la base, contrairement à une requête de sélection qui renvoie un ResultSet. • Déconnexion : • La méthode close() permet de libérer les ressources prises par la création d'objets de type ResultSet, Statement, et Connection. • Elle existe pour chacune de ces interfaces. Elle est le plus souvent employée pour une Connection, car elle libère en même temps toutes les ressources qui lui sont associées. Java DataBase Connectivity IvMad - 2012 Structure d'une application JDBC import import import import import java.sql.DriverManager; java.sql.Connection; java.sql.Statement; java.sql.ResultSet; java.sql.SQLException; public class exempleJDBC { try { // chargement du pilote // ouverture de connexion // exécution d’une requête // Traitement des résultats // Fermeture de la connexion } catch (Exception ex) { } } // // // // // gestion des pilotes une connexion à la BD une instruction un résultat (lignes/colonnes) une erreur 8 Java DataBase Connectivity IvMad - 2012 9 Connexion à une base de données import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; public class JdbcExample2 { public static void main(String args[]) { Connection con = null; try { Class.forName("com.mysql.jdbc.Driver"); con = DriverManager.getConnection ("jdbc:mysql://localhost:3306/hotel","user","123456"); if (!con.isClosed()) System.out.println("Connexion au serveur MySQL par TCP/IP..."); } catch(Exception e) { System.err.println("Exception: " + e.getMessage()); } finally { try { if (con != null) con.close(); } catch(SQLException e) {} } } } Java DataBase Connectivity IvMad - 2012 10 JDBC - Java Database Connectivity • Déclaration du pilote JDBC • Méthode de chargement explicite d'un pilote : void loadDriver() throws ClassNotFoundException { Class.forName("com.mysql.jdbc.Driver"); } • L'appel à forName déclenche un chargement dynamique du pilote. • Class.forName(String className) : Retourne la classe d'objet associé à la classe ou l'interface donné avec le nom de la chaîne de caractères. • Un programme peut utiliser plusieurs pilotes, un pour chaque base de données. • Le pilote doit être accessible à partir de la variable d'environnement CLASSPATH pour être accessible en permanence le temps de l'exécution. Java DataBase Connectivity IvMad - 2012 11 JDBC - Java Database Connectivity • Connexion à la base de données • Méthode d'ouverture d'une nouvelle connexion : Connection newConnection() throws SQLException { final String url = "jdbc:mysql://localhost/test"; Connection conn = DriverManager.getConnection(url,"user","pass"); return conn; } • L'URL est de la forme : jdbc:sous-protocole:sous-nom Java DataBase Connectivity IvMad - 2012 JDBC - Java Database Connectivity • Interroger une base de données • Méthode de composition d'une requête SQL de type SELECT : // Définir la requête dans une chaîne de caractères String query = "SELECT nom,prenom,age FROM etudiant"; // Envoi de la requête et récupération du résultat ResultSet rs = st.executeQuery(query); // Traitement des résultats while (rs.next()) { // tant qu'il y a un suivant // Instruction qui récupèrent les données des champs-attributs // suivant le nombre d'enregistrements rs.getString("nom_champs"|numéro); rs.getInt("nom_champs"|numéro); rs.getFloat("nom_champs"|numéro), } 12 Java DataBase Connectivity IvMad - 2012 13 JDBC - Java Database Connectivity • Les requêtes en JDBC public void listPersons() throws SQLException { Connection conn = null; try { // créer une nouvelle connexion conn = newConnection(); Statement st = conn.createStatement(); // Définir, envoi de la requête et réception du résultat String query = "SELECT nom,prenom,age FROM etudiant"; ResultSet rs = st.executeQuery(query); // Traitement des résultats while (rs.next()) { System.out.println( // Récupération du contenu rs.getString("nom"), // de l'attribut 'nom' rs.getString("prenom"), // idem 'prenom' rs.getInt("age") ); // idem 'age' } } finally { // Fermer la connexion if (conn != null) conn.close(); } } Java DataBase Connectivity IvMad - 2012 14 JDBC - Java Database Connectivity • Modification de la base de données • Création d'une table dans la BD : une table "personne" avec trois attributs et une clé primaire non nulle et auto-incrémentée. Statement st = conn.createStatement(); String query = "CREATE TABLE personne (id int not null auto_increment, prenom VARCHAR(15), nom varchar(15), age INT, primary key(id))"; st.executeUpdate(query); Java DataBase Connectivity IvMad - 2012 15 JDBC - Java Database Connectivity • Modification de la base • Insertion de lignes Statement st = conn.createStatement(); int nb = st.executeUpdate( "INSERT INTO personne(Nom,Age) " + "VALUES ('" + nom + "', " + age + ")" ); • Ce principe est aussi utilisable pour les instructions UPDATE et DELETE. Statement st = conn.createStatement(); int nb = st.executeUpdate( "UPDATE personne " + "SET Age = " + age + " " + "WHERE Nom = '" + nom + "' " ); Java DataBase Connectivity IvMad - 2012 JDBC - Java Database Connectivity • Correspondance des types Java / SQL et la correspondance des dates et heures : 16 Java DataBase Connectivity IvMad - 2012 17 JDBC - Java Database Connectivity import java.sql.*; public class ExempleJdbc { // Connexion à une BD MySQL avec JDBC et requête SQL public ExempleJdbc() { try { this.loadDriver(); this.listPersons(); } catch (ClassNotFoundException e) { System.err.println("Pilote JDBC introuvable : " + e.getMessage()); } catch (SQLException e) { } } void loadDriver() throws ClassNotFoundException { Class.forName("com.mysql.jdbc.Driver"); } Connection newConnection() throws SQLException { final String url = "jdbc:mysql://localhost:3306/test"; Connection conn = DriverManager.getConnection(url, "client", "123456"); return conn; } public void listPersons() throws SQLException { Connection conn = null; try { conn = newConnection(); Statement st = conn.createStatement(); String query = "SELECT nom,prenom,age FROM personne ORDER BY age"; ResultSet rs = st.executeQuery(query); while (rs.next()) { System.out.printn(rs.getString(1)+" "+rs.getString("prenom")+" "+rs.getInt(3)); } } finally { if (conn != null) conn.close(); } } public static void main(String[] argv) { new ExempleJdbc(); } } Java DataBase Connectivity IvMad - 2012 18 JDBC - Java Database Connectivity • Création de la base de données "exemple" dans MySQL. • Se connecter en "root" sur MySQL et créer la base de données "exemple". • Se connecter sur la base "mysql" et définir les droits d'un utilisateur : C:/xampp/mysql/bin/mysql -u root -p mysql> create database exemple; mysql> use exemple; mysql> show databases; mysql> use mysql; mysql> grant all privileges on exemple.* to 'login'@'localhost' identified by 'mot_de_passe_base_de_données' with grant option; mysql> flush privileges; mysql> exit; • Les données d'identifications (login et mot_de_passe) serviront dans une application Java pour la connexion du pilot JDBC à la BD. Java DataBase Connectivity IvMad - 2012 19 JDBC - Rappel SQL • Rappel des commandes SQL de base : • Créer une base de données : CREATE DATABASE nom_BD; • Activer une base de données : USE nom_BD; • Créer une table : CREATE TABLE nom_table (liste d'attributs); • Insérer des données dans une table : INSERT INTO nom_table (liste d'attributs) VALUES (valeurs); • Afficher le contenu d'une table : SELECT * FROM nom_table; • Afficher la structure d'une table : DESCRIBE nom_table; • Description complète de SQL et ses commandes à l'adresse : http://valk.iut-gtr.univ-mrs.fr/bdr/BDR-mysql-3-2009-3.pdf • A consulter le site lié avec le cours est à l'adresse : http://valk.iut-gtr.univ-mrs.fr/java/POO-JDBC-I6-2012-3.pdf Java DataBase Connectivity IvMad - 2012 20 JDBC avec JCreator • Télécharger le pilote (driver) jdbc-mysql à partir de l’adresse: http://valk.iut-gtr.univ-mrs.fr/ic4/pilot/mysql-connector-java-5.1.13-bin.jar dans votre répertoire TP sur unité Z:\ • Lancer JCreator et ouvrir menu File pour créer un nouveau projet : File -> New -> Project -> Empty Project | Basic Java Application -> Next -> Renseigner Name pour nom du projet->Préciser Location sur disque Z:\répertoire de vos TP->Next -> onglet Required Libraries ->New -> Add -> New Archive -> choisir dans le répertoire TP le fichier mysqlconnector-java-5.1.18-bin.jar -> renseigner Name avec le nom du pilote com.mysql.jdbc.Driver -> cocher pilote -> Finish • Dans le cadre projet et fichier du JCreator le pilote jdbc-mysql apparait comme un package associé au projet. (voir transparent suivant) Java DataBase Connectivity IvMad - 2012 21 JDBC avec JCreator • Exécution du projet DBConnect avec pilote jdbc-mysql Java DataBase Connectivity IvMad - 2012 JDBC avec Eclipse • Pour ajouter le pilote jdbc-mysql dans l’IDE Eclipse choisir un projet et avec clic droit ouvrir Properties -> Java Build Path -> Libraries -> Add External Jars. Confirmer le choix (mysql-connector-java-5.1.18-bin.jar). 22 Java DataBase Connectivity IvMad - 2012 23 JDBC - connexion à la BD de la DOSI • Pour effectuer une connexion à une BD dans le cadre de nos TP, il faut se munir des identifiants fournis par la DOSI lors de votre demande de création de compte pour un accès à une BD MySQL. • Il faut récupérer les informations suivantes: Nom de la base : ID_Etudiant Utilisateur MySQL : ID_Etudiant Mot de passe MySQL pour l'utilisateur ID_Etudiant : XXXXX Nom du serveur MySQL : dbs-perso.luminy.univmed.fr Le code à importer pour l'instruction : Connection conn = DriverManager.getConnection( "jdbc:mysql://dbs-perso.luminy.univmed.fr:3306/ID_Etudiant","ID_Etudiant","xxxxx") • L'administration distante de votre BD est possible par le biais de l'application phpmyadmin : http://phpmyadmin.luminy.univmed.fr où il faut encore une fois s'identifier pour accéder et vérifier le résultat de votre application java-jdbc. (ne pas modifier la BD). Java DataBase Connectivity IvMad - 2012 24 JDBC - connexion à la BD de la DOSI import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.*; public class DBConnect { public static void main(String args[]) { Connection con = null; try { Class.forName("com.mysql.jdbc.Driver").newInstance(); con = DriverManager.getConnection ("jdbc:mysql://dbs-perso.luminy.univmed.fr:3306/DB", "etudiant", "pass"); if (!con.isClosed()) System.out.println("Connexion au serveur MySQL par TCP/IP..."); } catch (InstantiationException ex) { ex.printStackTrace(); } catch (IllegalAccessException ex) { ex.printStackTrace(); } catch (ClassNotFoundException cnfe) { System.out.println("Driver introuvable: " + cnfe.getMessage()); cnfe.printStackTrace(); } catch (SQLException sqle) { System.err.println("Exception: " + sqle.getMessage()); sqle.printStackTrace(); } finally { try { if (con != null) { con.close(); System.out.println("Database connection terminated..."); } } catch(SQLException e) {} } } } Java DataBase Connectivity IvMad - 2012 25 JTable - afficher des données dans une table • La classe JTable affiche des données dans un tableau • La classe TableModel contribue à la gestion des données • On peut fournir les données dans un tableau bidimensionnel d’objets : • Object[][]et utiliser le DefaultTableModel • mais il vaut mieux étendre AbstractTableModel. • Un tableau est entouré d’ascenseurs, en général car inséré dans JScrollPane • Les constructeurs: • JTable(int numRows, int numColumns) avec autant de cellules vides • JTable(Object[][] rowData, Object[] columnNames) avec les valeurs des cellules de rowData et noms de colonnes columnNames. • JTable(TableModel dm, TableColumnModel cm) avec modèle de • données et modèle de colonnes fournis. • JTable(TableModel dm, TableColumnModel cm, ListSelectionModel sm) Les trois modèles sont fournis. Java DataBase Connectivity IvMad - 2012 JTable - afficher des données dans une table import javax.swing.*; import java.awt.*; class TablePlanetes extends JPanel { private Object[][] cellules = { { "Mercure", new Double(2440), new Integer(0), "non"}, { "Vénus", new Double(6052), new Integer(0), "non"}, { "Terre", new Double(6378), new Integer(1), "non"}, { "Mars", new Double(3397), new Integer(2), "non"}, { "Jupiter", new Double(71492), new Integer(16), "oui"}, { "Saturne", new Double(60268), new Integer(18), "oui"} }; private String[] columnNames = { "Planète", "Rayon", "Lunes", "Gazeuse"}; public TablePlanetes() { setLayout(new BorderLayout()); JTable table = new JTable(cellules, columnNames); add(new JScrollPane(table), BorderLayout.CENTER); } public static void main(String args[]) { TablePlanetes window = new TablePlanetes(); JFrame mainFrame = new JFrame( "Affiche table" ); mainFrame.add( window, BorderLayout.CENTER ); mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE ); mainFrame.setSize( 300, 200 ); } } mainFrame.setVisible( true ); 26 Java DataBase Connectivity IvMad - 2012 27 Afficher le résultat d'une requête dans JTable • Créer une classe qui dérive de la classe AbstractTableModel qui utilise les données du ResultSet : le résultat d'une requête SQL. • Pour afficher le résultat, on intègre le JTable dans un Jpanel (JFrame). • Le diagramme suivant, représente les différents composants utilisés: Java DataBase Connectivity IvMad - 2012 28 Afficher le résultat d'une requête dans JTable • La classe ResultSetTableModel est chargée de fournir les données à JTable en redéfinissant les méthodes suivantes : • public int getColumnCount() - renvoi le nombre de colonnes • public int getRowCount() - renvoi le nombre de lignes • public String getColumnName( int column ) - pour utiliser dans JTable les noms des champs comme titres de colonnes • public Object getValueAt(int rowIndex, int columnIndex) - pour afficher dans les cellules JTable les valeurs des champs. • ResultSetMetaData rsmd = rs.getMetaData(); - on récupère la structure du résultat de la requête SQL. • NumOfCol = rsmd.getColumnCount(); - retourne le nombre de colonnes dans le ResultSet. • columnNames[i] = new String(rsmd.getColumnName(i+1)); - obtient le nom du ième attribut de la table dans le ResultSet. • cellules = new String[rowCount][NumOfCol]; - les valeurs dans le ResultSet Java DataBase Connectivity IvMad - 2012 29 Afficher le résultat d'une requête dans JTable • Déterminer le nombre de lignes dans le ResultSet • rs.last(); - se positionner à la dernière ligne du ResultSet rowCount = rs.getRow(); - Récupérer le numéro de la ligne rs.beforeFirst(); - Revenir au début du ResultSet • Obtenir les valeurs des cellules de la table • cellules[j][i] = new String(rs.getString(i+1)); • Modèle par défaut pour JTable avec les lignes et colonnes: • DefaultTableModel model = new DefaultTableModel(cellules,columnNames); • Création de l'objet JTable • JTable table = new JTable(model); • La fenêtre, le gestionnaire de placement et les ascenseurs • JFrame mfr = new JFrame( "Résultat de la requête SQL" ); • mfr.setLayout( new BorderLayout() ); • mfr.add( new JScrollPane(table), BorderLayout.CENTER ); Java DataBase Connectivity IvMad - 2012 30 Afficher le résultat d'une requête dans JTable • Une interface SQL pour faciliter l'interrogation de la BD par une liste déroulante de requêtes prédéfinies : import javax.swing.*; public class interfaceSQL { public interfaceSQL() { String[] choix = { "SELECT prenom, nom, age FROM etudiant", "SELECT * FROM etudiant ORDER BY moyenne DESC", "SELECT * FROM etudiant ORDER BY matiere ASC", "SELECT * FROM etudiant ORDER BY age DESC" }; String s = (String)JOptionPane.showInputDialog( null, "Choisir une requete", "Liste de requetes SQL", JOptionPane.PLAIN_MESSAGE, null, choix, "SQL" ); new GetSQLResult(s); } } Java DataBase Connectivity IvMad - 2012 Afficher le résultat d'une requête dans JTable • Lancer une requête : • Résultat de la requête : 31