Professional Documents
Culture Documents
M. Belguidoum (UMC)
Programmation rseau
1 / 52
Plan
1 2 3 4 5
Introduction Le paquetage java.sql Mise en uvre de JDBC Equivalence des types java-SQL Fonctionnalits supplmentaires de JDBC
M. Belguidoum (UMC)
Programmation rseau
2 / 52
Introduction
Objectifs de JDBC
Permettre aux programmeurs Java d'crire un code indpendant de la base de donnes et du moyen de connexion utilis API JDBC (Java DataBase Connectivity) 3.0
interface uniforme permettant un accs homogne aux SGBD simple mettre en uvre indpendant du SGBD support supportant les fonctionnalits de base du langage SQL
M. Belguidoum (UMC)
Programmation rseau
3 / 52
Introduction
JDBC : introduction
JDBC (Java Data Base Connectivity) est une API permettant l'accs des bases de donnes relationnelles partir du langage Java l'accs aux bases de donnes est ralis en trois tapes :
la cration d'une connexion la base. l'envoi d'instructions SQL. l'exploitation des rsultats provenant de la base. JDBC est reprsente par le paquetage java.sql (depuis la version
1.1 du JDK)
M. Belguidoum (UMC)
Programmation rseau
4 / 52
Introduction
chaque SGBD utilise un pilote (driver) qui lui est propre et qui permet de convertir les requtes JDBC dans le langage natif du SGBD le driver est un ensemble de classes qui implantent les interfaces de JDBC les drivers dont le lien entre le programme Java et le SGBD ces drivers dits JDBC existent pour tous les principaux SGBD : Oracle, Sybase, Informix, DB2, MySQL,...
M. Belguidoum (UMC)
Programmation rseau
5 / 52
Introduction
JDBC : introduction
J2SE (Java 2 Standard Edition), permet de convertir les appels JDBC en appels ODBC (Open Database Connectivity). ODBC est fourni en standard sur les plates-formes Windows et permet la connexion des bases de natures diverses (Access, SQL Server, Oracle, ...). les pilotes de type 2 : ils sont crits, en partie, en Java, mais dpendent malgr tout de code natif. En termes de portage d'application Java, ces types de pilotes prsentent quelques lacunes. les pilotes de type 3 : ce type de pilote passe par un autre pilote JDBC intermdiaire (frquemment de type 1 ou 2). Il s'agit certainement du type de pilote le moins utile des quatre proposs. les pilotes de type 4 : leur code est crit en Java, donc portable. Ces pilotes sont fournis par presque tous les constructeurs de bases de donnes. Chaque pilote tant adapt une base de donnes particulire. Ces drivers constituent la meilleure solution pour le portage des applications Java.
M. Belguidoum (UMC) Programmation rseau 6 / 52
Introduction
M. Belguidoum (UMC)
Programmation rseau
7 / 52
Introduction
API native
M. Belguidoum (UMC)
Programmation rseau
8 / 52
Introduction
M. Belguidoum (UMC)
Programmation rseau
9 / 52
Introduction
M. Belguidoum (UMC)
Programmation rseau
10 / 52
Introduction
http://developers.sun.com/product/jdbc/drivers
choix entre vitesse, abilit et portabilit. Programme "standalone", avec une interface graphique qui s'excute toujours sur un systme Windows peut tirer bnce de performances d'un driver type 2 (driver code-natif). Une applet peut ncessiter un driver de type 3 (pour passer un rewall). Une servlet dploye sur de multiples plateformes peut ncessiter la souplesse oerte par des drivers de type 4. ...
M. Belguidoum (UMC)
Programmation rseau
11 / 52
Le paquetage java.sql
JDBC : le paquetage
java.sql
M. Belguidoum (UMC)
Programmation rseau
12 / 52
Le paquetage java.sql
: renvoie une instance de Connection Connection : connexion une base Statement : instruction SQL PreparedStatement : instruction SQL paramtre CallableStatement : procdure stocke dans la base ResultSet : n-uplets rcuprs par une instruction SQL ResultSetMetaData : description des n-uplets rcuprs DatabaseMetaData : informations sur la base de donnes
Driver
M. Belguidoum (UMC)
Programmation rseau
13 / 52
Le paquetage java.sql
DriverManager Date
: date SQL Time : heures, minutes, secondes SQL TimeStamp : comme Time, avec une prcision la microseconde Types : constantes pour dsigner les types SQL (conversions)
M. Belguidoum (UMC)
Programmation rseau
14 / 52
Le paquetage java.sql
mthode getMessage() : pour obtenir le message en clair de l'erreur renvoie galement des informations spciques au SGBD :SQLState et le code d'erreur SGBD
: avertissements SQL DataTruncation : lorsqu'une valeur est tronque lors d'une conversion SGBD -Java
SQLWarning
M. Belguidoum (UMC)
Programmation rseau
15 / 52
Le paquetage java.sql
JDBC :
DriverManager
M. Belguidoum (UMC)
Programmation rseau
16 / 52
1 2 3 4 5 6 7
Importer le package java.sql Enregistrer le driver JDBC Etablir la connexion au SGBD Crer une requte (ou instruction SQL) Excuter la requte Traiter les donnes retournes Fermer la connexion
M. Belguidoum (UMC)
Programmation rseau
17 / 52
Interface Driver
ncessite un URL vers la base renvoie une instance de l'interface Connection (null si le driver ne convient pas)
L'instance de Connection obtenue permet de lancer des requtes URL pour accder la base (syntaxe dpend du SGBD cible)
jdbc:<sous-protocole>:<nom-BD>?param=valeur, ... sous-protocole : mysql nom-BD : //foo.loria.fr:1114:maBase
exemples
= = = =
M. Belguidoum (UMC)
Programmation rseau
18 / 52
Rle de la classe DriverManager : elle gre les dirents drivers (instances de Driver) Pour qu'un driver soit disponible, il faut charger sa classe en mmoire
Utiliser la mthode forName de la classe Class avec en paramtre le nom complet de la classe du driver : Class.forName("driverName") cre une instance de la classe enregistre cette instance auprs de la classe DriverManager
Class . forName (" oracle . jdbc . driver . OracleDriver " ); // pilote Oracle Class . forName (" sun . jdbc . odbc . JdbcOdbcDriver " ); // pilote ODBC Class . forName (" com . mysql . jdbc . Driver " ); // pilote MySQL
M. Belguidoum (UMC)
Programmation rseau
19 / 52
On utilise la mthode getConnection() de DriverManager avec trois arguments : l'URL (Uniform Ressource Locator) de la base de donnes de la forme :
jdbc:typedriver:base
le DriverManager essaie tous les drivers enregistrs (chargs en mmoire avec Class.forName()) jusqu' ce qu'il trouve un driver qui lui fournisse une connexion
M. Belguidoum (UMC)
Programmation rseau
20 / 52
Une fois une Connection cre on peut l'utiliser pour crer et excuter des requtes (statements) SQL. 3 types (interfaces) d'objets statement :
Statement : requtes simples (SQL statique) PreparedStatement : requtes prcompiles (SQL dynamique si
3 mthodes d'excutions :
executeUpdate : pour les requtes qui ne retournent pas de rsultat (INSERT, UPDATE, DELETE, CREATE TABLE et DROP TABLE) execute : quand on ne sait pas si la requte retourne ou non un
ResultSet
Programmation rseau
21 / 52
String myQuery = " SELECT prenom , nom , email " + " FROM employe " + " WHERE ( nom =' Dupont ') AND ( email IS NOT NULL ) " + " ORDER BY nom " ; ResultSet resultat = state . executeQuery ( myQuery );
M. Belguidoum (UMC)
Programmation rseau
22 / 52
d'accder aux champs des n-uplets slectionns seules les donnes demandes sont transfres en mmoire par le driver JDBC il faut donc les lire "manuellement" et les stocker dans des variables pour un usage ultrieur Les ranges du ResultSet se parcourent itrativement ligne (row) par ligne
boolean next() : permet d'avancer la ligne suivante, retourne false si pas de ligne suivante Plac avant la premire ligne la cration du ResultSet Les colonnes sont rfrences par leur numro ou par leur nom L'accs aux valeurs des colonnes se fait par des mthodes (String nomCol) ou getXXX(int numCol) o XXX dpend du type de la colonne dans la table SQL Pour les trs gros row, on peut utiliser des streams.
Programmation rseau 23 / 52
M. Belguidoum (UMC)
java . sql . Statement stmt = conn . createStatement (); ResultSet rs = stmt . executeQuery (" SELECT a , b , c FROM Table1 " ); while ( rs . next ()) { int i = rs . getInt ("a " ); // rs . getInt (1); en SQL les numros de c // dbutent 1 String s = rs . getString ("b" ); // rs . getString (2); byte b [] = rs . getBytes ("c" ); // rs . getBytes (3); System . out . println ( " ROW = " + i + " " + s + " " + b [0]); }
M. Belguidoum (UMC)
Programmation rseau
24 / 52
ResultSet
excuter next() au moins une fois pour avoir le premier Impossible de revenir au n-uplet prcdent ou de parcourir l'ensemble dans un ordre non squentiel On peut parcourir le ResultSet d'avant en arrire : next() vs.
previous()
en dplacement absolu (aller la n-ime ligne) : absolute(int row), first(), last(), ... en dplacement relatif (aller la n-ime ligne partir de la position courante du curseur) : relative(int row), afterLast(), beforeFirst(), ...
M. Belguidoum (UMC)
Programmation rseau
25 / 52
ResultSet
Mthodes de parcours
first() : Positionne sur la premire ligne (1er enregistrement) last() : Positionne sur la dernire ligne (dernier enregistrement) next() : Passe la ligne suivante previous() : Passe la ligne prcdante beforeFirst() : Positionne avant la premire ligne afterLast() : Positionne aprs la dernire ligne absolute(int) : Positionne une ligne donne relative(int) : Dplacement d'un nombre de lignes donn par
boolean isFirst() : True si curseur positionn sur la premire ligne boolean isBeforeFirst() : True si curseur positionn avant la
boolean isLast() : True si curseur positionn sur la dernire ligne boolean isAfterLast() : True si curseur positionn aprs la dernire
M. Belguidoum (UMC) Programmation rseau 26 / 52
Pour terminer proprement un traitement, il faut fermer les dirents espaces ouverts. Le ramasse-miettes peut le faire mais de faon moins ecace Chaque objet possde une mthode close() :
resultset . close (); statement . close (); connection . close ();
M. Belguidoum (UMC)
Programmation rseau
27 / 52
M. Belguidoum (UMC)
Programmation rseau
28 / 52
Exemple complet
import java . sql .*; public class PrintAllEmployees { public static void main ( String [] args ) throws SQLException , ClassNotFoundException { String dbUrl = " jdbc : mysql :// localhost :3306/ yaps " ; String user = " root " , password = ""; // Chargement dynamique du driver Class . forName (" com . mysql . jdbc . Driver " ); Connection conn ; // Etablissement de la connexion conn = DriverManager . getConnection ( dbUrl , user , password ); Statement st = conn . createStatement (); // Cration d 'un statement String anSQLquery = " SELECT prenom , nom , age FROM employe "; // Excution de la requte ResultSet r = st . executeQuery ( anSQLquery ); // Parcours du rsultat while (r. next ()) { String nom = r. getString (" nom " ); int age = r. getInt (" age " ); System . out . println ( nom + " , " + age + " ans " ); } r. close (); st . close (); conn . close (); } }
M. Belguidoum (UMC) Programmation rseau 29 / 52
String anSQLquery = " SELECT prenom , nom , age FROM employe " ; // Cration d 'un statement Statement st = conn . createStatement (); // Excution de la requte ResultSet r = st . executeQuery ( anSQLquery );
M. Belguidoum (UMC)
Programmation rseau
30 / 52
String query = " SELECT nom , age ... "; ResutSet r = st . executeQuery ( query ); while (r. next ()) { String nom = r. getString (" nom " ); int age = r. getInt (2); // ... }
M. Belguidoum (UMC)
Programmation rseau
31 / 52
Dans le cas d'une modication de donne (INSERT, UPDATE, DELETE), on utilise la mthode executeUpdate(...) qui renvoie un entier spciant le nombre d'enregistrements modis
String reqSql = " DELETE FROM ... "; int n = st . executeUpdate ( reqSql )
M. Belguidoum (UMC)
Programmation rseau
32 / 52
Excuter des procdures stockes : java.sql.CallableStatement Utiliser des transactions Accder aux mta-donnes (schma) de la base :
java.sql.DatabaseMetaData
M. Belguidoum (UMC)
Programmation rseau
33 / 52
Requtes pr-compiles
La plupart des SGBD ore la possibilit de n'analyser qu'une seule fois une requte JDBC permet de bncier de cette fonctionnalit L'objet PreparedStatement envoie une requte sans paramtres la base de donnes pour prcompilation et spciera le moment voulu la valeur des paramtres
plus rapide qu'un Statement classique le SGBD n'analyse qu'une seule fois la requte (recherche d'une stratgie d'excution adquate) pour de nombreuses excutions d'une mme requte SQL avec des paramtres variables
M. Belguidoum (UMC)
Programmation rseau
34 / 52
les paramtres sont spcis par un " ?" ils sont ensuite instancis par les mthodes setInt(), setString(), setDate(),... ces mthodes ncessitent 2 arguments (setInt(n, valeur))
le premier (int) indique le numro relatif de l'argument dans la requte le second indique la valeur positionner setNull(n,type) positionne le paramtre NULL (SQL)
M. Belguidoum (UMC) Programmation rseau
35 / 52
PreparedStatement ps = c. prepareStatement (" UPDATE emp SET sal = ? " + " WHERE name = ?" ); for ( int i = 0; i < 10; i ++) { ps . setFloat (1 , salary [i ]); ps . setString (2 , name [i ]); int count = ps . executeUpdate (); }
M. Belguidoum (UMC)
Programmation rseau
36 / 52
Avantages des
PreparedStatement
Traitement plus rapide si utiliss plusieurs fois avec plusieurs paramtres Amlioration de la portabilit car les mthodes setXXX() n'ont pas tenir compte des dirences entre SGBD Exemple : les SGBD n'utilisent pas tous les mmes formats de date ('JJ/MM/ AA' ou 'AAAA-MM-JJ') ou de chanes de caractres (pour les caractres d'chappement)
M. Belguidoum (UMC)
Programmation rseau
37 / 52
procdures permettant de fournir la mme fonctionnalit plusieurs utilisateurs procdure stocke dans la base ct serveur JDBC ore une interface ddie
CallableStatement drive de l'interface PreparedStatement gre le retour de valeur avec ResultSet
Comment
M. Belguidoum (UMC)
Programmation rseau
38 / 52
encadre par des accolades {...} utilisation du prxe call la procdure renvoie une valeur : { ? = call
nomProcdure(?,?,...)}
M. Belguidoum (UMC)
Programmation rseau
39 / 52
CallableStatement testCall ; testCall = conn . prepareCall ( "{ call setSalary (? ,?) }" ); testCall . setString (1 , " EUR " ); testCall . setLong (2 , 2000); testCall . execute ();
M. Belguidoum (UMC)
Programmation rseau
40 / 52
Un PreparedStatement peut retourner des donnes grce un Les procdures stockes tendent le modle
ResultSet
appel de la procdure prcd du passage des paramtres in et out grce aux mthodes setXXX() type des paramtres out et in/out grce la mthode
registerOutParameter()
excution de la requte grce executeQuery(), executeUpdate() ou execute() rcupration des paramtres out et in/out grce aux mthodes
getXXX()
M. Belguidoum (UMC)
Programmation rseau
41 / 52
create or replace procedure augmentation ( unDept in integer , pourcentage in number , cout out number ) is begin update emp set sal = sal * (1 + pourcentage / 100) where dept = unDept ; select sum ( sal ) * pourcentage / 100 into cout from emp where dept = unDept ; end ;
M. Belguidoum (UMC)
Programmation rseau
42 / 52
Exemple suite
CallableStatement
CallableStatement csmt = conn . prepareCall ( "{ call augmentation (? , ? , ?) } " ); // 2 chiffres aprs la virgule pour 3 me paramtre csmt . registerOutParameter (3 , Types . DECIMAL , 2); // Augmentation de 2 ,5 % des salaires du dept 10 csmt . setInt (1 , 10); csmt . setDouble (2 , 2.5); csmt . executeQuery (); double cout = csmt . getDouble (3); System . out . println ( " Cout total augmentation : " + cout );
M. Belguidoum (UMC)
Programmation rseau
43 / 52
Transactions
Les nouvelles connexions sont initialement en mode auto-commit => commit implicite aprs chaque requte SQL Pour dnir une transaction compose de plusieurs requtes SQL, il faut dsactiver l'auto-commit : conn.setAutoCommit(false) Un appel commit() ou rollback() va alors crer implicitement une nouvelle transaction
M. Belguidoum (UMC)
Programmation rseau
44 / 52
Transactions : Exemple
// Dsactiver l 'auto - commit conn . setAutoCommit ( false ); try { // les requtes SQL suivantes constituent // une seule transaction st . executeUpdate (" INSERT ... " ); st . executeUpdate (" DELETE ... " ); st . executeUpdate (" UPDATE ... " ); // valider la transaction conn . commit (); st . close (); } catch ( java . sql . SQLException e) { conn . rollback (); }
M. Belguidoum (UMC)
Programmation rseau
45 / 52
JDBC permet de rcuprer des informations sur le type de donnes que l'on vient de rcuprer par un SELECT (interface ResultSetMetaData) et sur la base elle-mme (interface DatabaseMetaData) Interface ResultSetMetaData
mthode getMetaData() permet d'obtenir des informations sur les types de donnes du ResultSet elle renvoie des instances de ResultSetMetaData on peut connatre :
le nombre de colonne : le nom d'une colonne : le nom de la table :
M. Belguidoum (UMC)
Programmation rseau
46 / 52
Exemple : ResultSetMetaData
ResultSet rs = st . executeQuery ( " SELECT * FROM emp " ); ResultSetMetaData rsmd = rs . getMetaData (); int nbColonnes = rsmd . getColumnCount (); for ( int i = 1; i <= nbColonnes ; i ++) { String typeColonne = rsmd . getColumnTypeName ( i ); String nomColonne = rsmd . getColumnName (i ); System . out . println ( " Colonne " + i + " de nom " + nomColonne + " de type " + typeColonne ); }
M. Belguidoum (UMC)
Programmation rseau
47 / 52
Interface DatabaseMetaData
informations sur la base de donnes mthode getMetaData() de l'objet Connection dpend du SGBD avec lequel on travaille elle renvoie des instances de DatabaseMetaData on peut connatre :
les tables de la base : getTables() le nom de l'utilisateur : getUserName()...
M. Belguidoum (UMC)
Programmation rseau
48 / 52
CLOB et BLOB
M. Belguidoum (UMC)
Programmation rseau
49 / 52
Lire un BLOB
String q = " select image from userImages " ResultSet rs = stmt . executeQuery (q ); while ( rs . next ) { Blob b = rs . getBlob (" image " ); InputStream stream = b. getBinaryStream (); // ... }
M. Belguidoum (UMC)
Programmation rseau
50 / 52
Conclusion
le concept de Driver masque au maximum les dirences des SGBD API de bas niveau : il faut connatre SQL
JDBC n'eectue aucun contrle sur les instructions SQL Correspondance entre classes Java et relations est un travail de bas niveau
M. Belguidoum (UMC)
Programmation rseau
51 / 52
Rfrences
http://java.sun.com/developer/Books/JDBCTutorial/
slides de Olivier Perrin et philippe Genoud Christian Soutou, "Apprendre SQL avec MySQL : Avec 40 exercices corrigs"
M. Belguidoum (UMC)
Programmation rseau
52 / 52