JDBC de Base

Published on July 2022 | Categories: Documents | Downloads: 3 | Comments: 0 | Views: 67
of 13
Download PDF   Embed   Report

Comments

Content

 

Présentation 

JDBC de base  

Université Unive rsité de Nice - Sophi Sophiaa Anti Antipolis polis Richard Grin Version Versio n 3.1 – 16/8/07 16/8/07

JDBC (Java Data Base Connectivity) permet l'accès à des bases de données avec le langage SQL, depuis un programme en Java Il est fourni par le paquetage java.sql L’API JDBC est presque totalement indépendante des SGBDs (quelques méthodes ne ne peuvent être être utilisées qu’avec certains certains SGBDs mais ne doivent être utilisées qu’en cas de nécessité impérieuse pour améliorer les performances)

R. Grin

 Versions de SQL supportées Les premières versions de JDBC supportent le standard SQL-2 Entry Level  JDBC 2 et 3 offrent en plus des fonctionnalités de SQL3  Pour des raisons d'efficacité un driver peut utiliser les possibilités particulières d'un SGBD (c'est permis par JDBC), mais au détriment de la portabilité  JDBC 4 accompagne Java 6 ; il utilise les annotations et apporte plus de facilités pour l’écriture du code JDBC

page 2

Contenu de java.sql



R. Grin

JDBC

page 3

Ce paquetage contient un grand nombre d'interfaces et quelques classes  Les interfaces constituent l’interface de programmation  JDBC ne fournit pas les classes qui implantent les interfaces 

R. Grin

JDBC

page 4

Drivers

Types de drivers

Pour travailler avec un SGBD il faut disposer de classes qui implantent les interfaces de JDBC  Un ensemble de telles classes est désigné sous le nom de driver JDBC  Les drivers dépendent du SGBD auquel ils permettent d'accéder   Tous les SGBD importants importants du marché ont un (et même plusieurs) driver JDBC, fourni par l'éditeur du SGBD ou par des éditeurs de logiciels indépendants

Type 1 : pont JDBC-ODB JDBC-ODBC C Type 2 : driver driver qui fai faitt appel à des fon fonction ctionss natives non Java (le plus souvent en langage C) de l'API du SGBD que l'on veut utiliser   Type 3 : driver qui permet l'utilisation d'un serveur 



R. Grin

JDBC

page 5





middleware 

Type 4 : driver écrit entièrement entièrement en Java, qui utilise le protocole réseau du SGBD

R. Grin

JDBC

page 6

1

 

Type 2 : utilise une API native

Type 1 : pont JDBC-ODBC Application Java

Application Java

Driver JDBC

(en Java)

Driver ODBC

(pas en Java)

Les méthodes du driver JDBC font font appel à des

Partie en Java

fonctions d'une API du SGBD écrite dans un autre langage que Java

Les méthodes du driver JDBC font appel à des fonctions en langage C d'un driver ODBC

SGBD

JDBC

page 7

Type 3 : accès accès à un serv serveur eur middleware 

R. Grin

JDBC

direct auApplication SGBDJava

Driver en Java

Driver en Java

Protocole du serveur  middleware Serveur middleware

Les méthodes du driver JDBC utilisent des sockets pour  dialoguer avec le SGBD selon son protocole réseau

Protocole du SGBD

SGBD R. Grin

JDBC

page 8

Type 4 : 100 % Java avec accès

Application Java

Les méthodes du driver JDBC se connectent par socket  au serveur middleware et lui envoient les requêtes SQL ; le serveur middleware les traitent en se connectant au SGBD

Driver 

Protocole du SGBD

SGBD

R. Grin

(en Java) (pas en Java)

Partie native

SGBD page 9

Types de drivers et applet untrusted  Une applet ne peut pas charger à distance du code natif (non Java) ; elle ne peut donc pas utiliser les drivers de type 1 et 2  Pour des raisons de sécurité, une applet untrusted (qui fonctionne dans le bac à sable ; voir cours sur la sécurité) ne peut échanger des données par sockets qu'av qu'avec ec la machine d'où elle provient, ce qui implique des contraintes avec les drivers de type 3 et 4 

R. Grin

JDBC

pa ge 10

Driver de type 3 et applet untrusted  Le serveur middleware doit être sur la même machine que le serveur HTTP

Code Java Applet Driver en Java connexion par socket

Serveur HTTP

Serveur middleware

SGBD R. Grin

JDBC

page 11

R. Grin

JDBC

pa ge 12

2

 

Driver de type 4 et applet untrusted  Code Java Le serveur HTTP doit être sur la même machine que le SGBD

Applet

Driver en Java

Travailler avec JDBC connexion par socket

Serveur HTTP

R. Grin

SGBD

JDBC

page 13

R. Grin

Pour utiliser JDBC A l’exécution, ajouter le chemin des classes du (des) driver dans le classpath (option -classpath de la commande java)  Par exemple, si Oracle est installé dans /oracle, le driver peut être dans le fichier  /oracle/jdbc/lib/ojdbc14.jar

et l’application sera lancée par la commande



Importer le paquetage java.sql (et java.mat h si on utilise la classe BigDecimal ) : import java.sql.*;



Charger en mémoire la classe du (des) driver (driver de type 4 fourni par Oracle pour cet exemple) avant d'utiliser JDBC : Class.forName("oracle.jdbc.OracleDriver");

java –classpath /oracle/jdbc/lib/ojdbc14.jar:… ...

JDBC

pa ge 14

Dans les classes qui utilisent JDBC



R. Grin

JDBC

page 15

Inutile avec JDBC 4 !

R. Grin

JDBC

pa ge 16

Étapes du travail avec une base de données avec JDBC 1. Ouvrir une connexion (Connection) 2. Créer des instructions SQL (Statement, PreparedStatement ou CallableStatement ) 3. Lancer l'exécution de ces instructions : n n n

Classes et interfaces de JDBC

interroger la base (executeQuery()) ou modifier la base (executeUpdate()) ou tout autre ordre SQL (execute())

4. Fermer la connexion ( close()) R. Grin

JDBC

page 17

R. Grin

JDBC

pa ge 18

3

 

 Avertissement Dans la suite du cours on utilise des raccourcis tels que « insta instance nce de Connection »  Comme Connection est une interface, il faut

Nous étudierons tout d'abord les classes et méthodes de base de JDBC  Des nouvelles possibilités de JDBC 2 et 3, en





traduire par «Connection instance d’une implémente » classe qui

particulier sont à SQL3, seront abordées abordé es dans dcelles ans les lequi s par parties tiesliées « JDBC avancé » et « JDBC et objet-relat objet-relationnel ionnel »

R. Grin

JDBC

page 19

R. Grin

JDBC

pa ge 20

Interfaces principales

Classes principales

Driver : renvoie une instance de Connection  Conne Connection ction : connexion connexion à une base base  Stat Statement ement : ordre SQL  PreparedStatement : ordre SQL paramétré  CallableStatement : procédure stockée stockée sur le SGBD  ResultSet : lignes récupérées récupérées par un ordre ordre SELECT  ResultSetMetaData : description des lignes récupérées par un SELECT  DatabaseMetaData : informations sur la base de données

DriverManager : gère les drivers, lance les connexions aux bases  Date : dat datee SQL  Time : heures, minutes, secondes SQL  TimeS TimeStamp tamp : date et heu heure, re, ave avecc une précisi précision on à la microseconde  Types : constantes pour désigner désigner les types SQL (pour les conversions avec les types Java)



R. Grin

JDBC

page 21



R. Grin

JDBC

pa ge 22

Exceptions de JDBC 4 (1)

Exceptions SQLException SQLExcepti on : erreurs SQL  SQLWarning : avertissements SQL (classe fille de SQLException) ; le mécanisme de récupération des avertissements est est étudié plus loin  DataTruncation : avertit quand une une valeur est tronquée lors d'un transfert entre Java et le SGBD (classe fille de SQLWarning)





a 3 sous-classes pour distinguer différents types d’exception SQLNonTransientException : le problème ne peut être résolu sans une action externe ; inutile de réessayer la même action sans rien faire de spécial SQLTransientException : le problème peut avoir été résolu si on attend un un peu avant de ressayer  SQLRecoverableException : l’application peut résoudre le problème en exécutant une certaine action SQLException n

n

n

R. Grin

JDBC

page 23

R. Grin

JDBC

pa ge 24

4

 

Exceptions de JDBC 4 (2) 

Chaînage des exceptions

Classes filles de SQLNonTransientException : SQLDataException , SQLFeatureNotSupportedException ,

Une requête SQL peut provoquer plusieurs exceptions  On peut obtenir la prochaine exception par la 

SQLIntegrityConstraintViolationException , SQLInvalidAuthorizationException , , SQLNonTransientConnectionException SQLSyntaxErrorException 

getNextException() méthode Une exception peut avoir une cause ; on l'obtient par la méthode getCause()  Toutes ces exceptions peuvent être parcourues par une bou boucle cle « for for-ea -each ch » :



Classes filles de SQLTransientException : SQLTimeoutException , SQLTransactionRollbackException ,

catch(SQLE catch( SQLExce xcepti ption on ex) { for for ( (Th Thro rowa wabl ble e e : ex) { … }

SQLTransientConnectionException R. Grin

JDBC

R. Grin

page 25



La méthode connect() de Driver prend en paramètre un URL et renvoie une instance de l'interface Connection  Cette instance de Connection permettra de lancer des requêtes vers le SGBD  connect renvoie null si le driver ne convient pas pour se connecter à la base désignée par par l'URL 

JDBC

Un URL pour une base de données est de la forme :  jdbc:sous-protocole:base de donnée  Par exemple, pour Oracle :  jdbc:oracle:thin:@sirocco.unice.fr:1521:INFO  jdbc:oracle:thin:@sirocco.uni ce.fr:1521:INFO oracle:thin est le sous-protocole (driver (driver « thin » ; Oracle fournit aussi un autre type de driver) @sirocco.unice.fr:1521:INFO @sirocco.unice.fr:1521 :INFO désigne la base de données INFO située sur la machine sirocco (le ( le serveur du SGBD écoute sur le port 1521)  La forme exacte des parties sous-protocole et base de données dépend du SGBD cible n

n

Utilisée par DriverManager DriverManager ; pas visible par l’utilisateur de l’API

R. Grin

page 27

R. Grin

JDBC

pa ge 28

JDBC 4 et le driver

Gestionnaire de drivers La classe DriverManager gère les drivers (instances de Driver) disponibles pour les différents SGBD utilisés par le programme Java  Pour qu'un driver soit utilisable, on doit charger sa classe en mémoire : 

Class.forName("oracle.jdbc.OracleDriver"); 

pa ge 26

URL d'une base de données

Interface Driver



JDBC

La classe crée alors une instance d'elle même et enregistre cette instance auprès de la classe

JDBC 4 utilise un autre mécanisme pour charger le driver : il suffit d'indiquer le nom de la classe du driver dans un fichier META-INF/s METAINF/service ervices/jav s/java.sql a.sql.Drive .Driverr distr distribué ibué avec le driver JDBC  Il est alors inutile d’appeler la méthode



Class.forName

DriverManager

R. Grin

JDBC

page 29

R. Grin

JDBC

pa ge 30

5

 

Obtenir une connexion 

Connexions et threads

Pour obtenir une connexion connexion à un SGBD, on demande cette connexion connexion à la classe gestionnaire de drivers : static final static final Strin String g url = "jdbc:oracle:thin:@sirocco.unice.fr:1521:INFO"; Conn Connec ecti tion on co conn nn = DriverManager.getConnection(url, "toto", "mdp");



La classe DriverManager s'adre s'adresse sse à tour de rô rôle le à tous les drivers qui se sont enregistrés (méthode connect), jusqu'à ce qu'un driver lui fournisse une connexion (ne renvoie pas null) R. Grin

JDBC

page 31

Les connexions sont des ressources coûteuses, et surtout surtout longues à obten obtenir  ir   On peut donc être être tenté de les réutiliser dans 

threads plusieurs Mais, attention, lesdifférents connexions ne peuvent être partagées par plusieurs threads  À la place, utiliser utiliser les pools de connexions fournis avec les « sources sources de donnée donnéess » (étud (étudiées iées ddans ans une autre partie du cours) 

R. Grin

Transactions

JDBC

pa ge 32

Niveau d’isolation

Par défaut la connexion est en «  auto-commit » : un commit est automatiquement automatiquement lancé après chaque ordre SQL qui modifie la base  Le plus souvent il faut enlever l'auto-commit : 



Le niveau d’isolation d’une transaction peut être modifié modifi é: conn.setTransactionIsolation( Connection.TRANSACTION_SERIALIZABLE) ;

conn.setAutoCommit(false) 

Il faut alors explicitement valider ou annuler la transaction par  n

conn.commit()

n

conn.rollback()

R. Grin

JDBC

page 33

R. Grin

JDBC

pa ge 34

Exécution de l’instruction SQL simple

Instruction SQL simple Instance de l'interface Statement  La création est effectuée par la méthode createStatement() de Connection :





La méthode à appeler dépend de la nature nature de l'ordre SQL que l’on veut exécuter : consultation (select) : executeQuery() renvoie un ResultSet pour récupérer les lignes lignes une à une modification des données (update, insert, delete) ou ordres DDL (create table,…) : executeUpdate() renvoie le nombre de lignes modifiées si on ne connaît pas pas à l'exécution la nature de l'ordre SQL à exécuter ou si l'ordre peut renvoyer plusieurs résultats : execute() n

Statemen Stat ement t stmt stmt = connexi connexion. on.cre create ateSta Stateme tement() nt(); ;

n

n

R. Grin

JDBC

page 35

R. Grin

JDBC

pa ge 36

6

 

Interface ResultSet

Consultation des données (SELECT) 

executeQuery() ResultSet



ResultSet

Statem Sta tement ent stmt stmt = conn.cre conn.create ateStat Statemen ement() t(); ; // rset contie contient nt les lignes lignes renvoyées renvoyées Re Resu sult ltSe Set t rset rset =

renvoie une instance de

va permettre de parcourir toutes les lignes renvoyées par le select

stmt.executeQuery("SELECT nomE FROM emp"); 

// On récupère récupère c chaque haque ligne ligne une à une while whi le (rset. (rset.next next()) ()) System.out.p System .out.println rintln (rset.getStri (rset.getString(1)); ng(1)); // ou . . . (rset.getString("nomE")); stmt.close();

La première colonne a le numéro 1

Voir plus loin le transparent sur la R. fermeture Grin des ressources

JDBC

page 37

ResultSet est positionné Au début,ligne posit ionné avant première et il faut donc commencer parlale faire avancer à la première ligne en appelant appelant la méthode next()  Cette méthode permet de passer passer à la ligne suivante ; elle renvoie true si cette ligne suivante existe et false sinon R. Grin

Interface ResultSet 

n

n

colonne, pas préfixé par un nom de table ; dans le cas d’une jointure utiliser un alias de colonne)

XXX désigne le type Java de la valeur v aleur que l'on va récupérer, par exemple String, Int ou Double  Par exemple, getInt renvoie un int



JDBC

pa ge 38

ResultSet Result Set - perfor performance mancess

Quand ResultSet est positionné positionné sur une ligne les méthodes getXXX getXXX permettent de récupérer les valeurs des colonnes de la ligne : getXXX(int numéroColonne) getXXX(String nomColonne) (nom simple d’une

R. Grin

JDBC

page 39

Quand le réseau est lent et que l’on veut récupérer de nombreuses lignes, il est parfois possible d’améliorer sensiblement les performances en modifiant le nombre de lignes récupérées à chaque fois par le ResultSet (il faut effectuer des tests pour chaque cas)  Pour cela, on utilise la méthode setFetchSize de Statement  C’est seulement une indication qu’on donne au driver ; il n’est pas pas obligé d’en tenir compte 

R. Grin

Types JDBC/SQL

JDBC

pa ge 40

Types JDBC/SQL (classe Types)

Tous les SGBD n'ont pas les mêmes types SQL ; même les types de base peuvent présenter des différences importantes  Pour cacher ces différences, JDBC définit ses propres types SQL dans la classe Types, sous forme de constantes nommées  Ils sont utilisés par les programmeurs quand ils doivent préciser un type SQL (setNull , setObject , registerOutParameter )  Le driver JDBC fait la traduction de ces types dans les types du SGBD 

R. Grin

JDBC

page 41

CHAR, VARCHAR, LONGVARCHAR  BINARY, VARBINARY, LONGVARBINARY  BIT, TINYINT, SMALLINT, INTEGER, BIGINT  REAL, DOUBLE, FLOAT  DECIMAL, NUMERIC  DATE, TIME, TIMESTAMP 

  

BLOB, CLOB ARRAY, DISTINCT, STRUCT, REF JAVA_OBJECT

R. Grin

JDBC

Types SQL3

pa ge 42

7

 

Correspondances avec getXXX()

Correspondances entre types Java et SQL Il reste le problème de la correspondance entre les types Java et les types SQL  Dans un programme JDBC, les méthodes getXXX, setXXX setXX X servent servent à préciser préciser cette corre correspond spondance ance  Par exemple, getString indique que l’on veut récupérer la donnée SQL dans une String  C'est le rôle du driver particulier à chaque SGBD de faire les traductions correspondantes ; une exception peut être lancée si ça n’est pas possible 

R. Grin

JDBC

On a une grande latitude ; ainsi, presque tous les types SQL peuvent être retrouvés par getString()  Cependant, des méthodes sont recommandées ; voici des exemples :



page 43

n

n

n n n

CHAR et VARCHAR VARCHAR : getString, getString, LONGVA LONGVARCHAR RCHAR : getAsciiStream et getCharacterStream BINARY BINAR Y et VARBIN VARBINARY ARY : getByt getBytes, es, LONGVARB LONGVARBINARY INARY : getBinaryStream REAL : getFloat, oat, DOUBLE DOUBLE et FLOA FLOAT T : getDouble getDouble DECIMAL DECIM AL et NUMERIC NUMERIC : getBigDecim getBigDecimal al DATE : getDa getDate, te, TIME TIME : getTime, getTime, TIMEST TIMESTAMP AMP : getTimestamp

R. Grin

Types Date en Java et en SQL java.sql contient une classe Date qui est utilisé par JDBC pour les échanges de dates entre Java et la base de données  Cette classe hérite de la classe java.util.Date  Elle correspond à un temps en millisecondes  Normalement les dates SQL ne contiennent pas d’indication sur l’heure dans la journée ; il faut utiliser les types SQL TIME et TIMESTAMP pour l’heure dans la journée  Pour passer de java.util.Date à java.sql.Date , utiliser la méthode getTime() JDBC

page 45





Pour passer de java.util.Date à java.sql.Date , utiliser la méthode getTime() : java.util.Da java.u til.Date te date = new java java.util.D .util.Date(); ate(); java java.s .sql ql.D .Dat ate e dateS dateSQL QL = new java.sql.Date(date.getTime()); java.s jav a.sql. ql.Tim Time e time = new Time(date.getTime()); java.s jav a.sql. ql.Tim Timesta estamp mp tim time e = new Timestamp(date.getTime());

R. Grin

n

java.text.DateFormat

calculs sur les dates avec la classe java.util.Calendar



Voir le cours sur les dates dans le support « Com Complé plémen ments ts di divers vers »

R. Grin

JDBC

pa ge 46

Statem Sta tement ent stmt = conn. conn.cre create ateStat Statemen ement() t(); ; ResultSet rs ResultSet rset et = stmt stmt.execu .executeQuery teQuery( ( "SELECT "SELEC T no nomE, mE, c comm omm FROM emp"); while whi le (rs (rset. et.next next()) ()) { nom = rset.getString("nomE"); commission = rset.getDouble("comm"); if (rset.wasNull()) System.out.println(nom + ": pas de comm"); else System.out.println(nom + " a " + commission + " € de co commi mmissi ssion" on"); ); }

Un petit rappel sur les dates en Java J ava : mise en forme avec la classe n

JDBC

 Valeur NULL  NULL

Manipulation des dates 

pa ge 44

Exemple



R. Grin

JDBC

page 47

R. Grin

JDBC

pa ge 48

8

 

Modification des données (INSERT, UPDATE, DELETE)

Instruction SQL paramétrée 

Statem Sta tement ent stmt = conn.crea conn.createSt teState atemen ment() t(); ; String ville = "NICE"; int nbLignes nbLignesMod Modifi ifiees ees = stmt.ex stmt.execu ecuteU teUpda pdate( te( "INSERT "INSER T INTO dept dept (dept, nomD, nomD, lieu) lieu) " + "VALUES (70, 'DIRECTION'," + "'" + ville + "')"); stmt.close();

R. Grin

 N'oubliez pas l'espace !

JDBC

page 49

La plupart des SGBD (dont Oracle) peuvent n'analyser qu'une seule fois une requête exécutée un grand nombre de fois durant une

connexion JDBC permet de profiter de ce type de fonctionnalité par l'utilisation de requêtes paramétrées ou de procédures stockées  Les requêtes paramétrées sont associées aux instances de l'interface PreparedStatement PreparedStatement qui hérite de l'interface Statement



R. Grin

Les "?" indiquent les emplacements des paramètres  Cette requête pourra être exécutées avec plusieurs couples de valeurs : (2500, ‘DUPOND’), (3000, ‘DURAND’), etc.



R. Grin

JDBC

page 51

Les valeurs des paramètres sont données par les méthodes setXXX(n, valeur)  On choisit la méthode setXXX suivant le type Java de la valeur que l'on veut v eut mettre dans la base de données  C'est au programmeur de passer une valeur Java J ava du bon type type à la métho méthode de setXXX setXXX  Le driver JDBC fait la conversion dans le bon format pour le SGBD 

R. Grin

Pr Prep epar ared edSt State ateme ment nt ps pstm tmt t = conn.prepareStatement(



"UPDATE "UPD ATE emp emp SET sal sal = ? " for (int (int i=0 i=0; ; i<10; i<10; i++) i++) {

JDBC

pa ge 52

Requête paramétrée - NULL  NULL

Requêtee para Requêt paramétrée métrée - Exemple Exemple

+ "WHERE nomE = ?");

pa ge 50

Requête paramétrée –  Valeurs des paramètres

Création d'une requête paramétrée Pr Prep epar ared edSta State teme ment nt ps pstm tmt t = conn.prepareS conn.p repareStateme tatement("UPD nt("UPDATE ATE emp SET sal = ?" + " WHERE nome = ?");

JDBC

commence à 1 commence et pas pas à 0

 pstmt.setDouble(1,employe[i].getSalaire());  pstmt.setString(2, employe[i].getNom());

Pour passer la valeur NULL NULL à la base de donnée, on peut utiliser la méthode setNull(n, type) (type de la classe Types) ou passer la valeur Java null si la méthode setXXX() attend un objet en paramètre n

n

 pstmt.executeUpdate(); }

R. Grin

JDBC

page 53

R. Grin

JDBC

pa ge 54

9

 

 Avantages des PreparedStatement Leur traitement est plus rapide s’ils sont utilisés plusieurs fois avec plusieurs paramètres  Ils améliorent aussi aussi la portabilité car les méthodes setXXX gèrent les différences entre SGBD

Procédures stockées





En effet,de lesdate SGBD n’utilisent pas les mêmes formats ( JJ/MM/AA ou tous AAAA-MM-JJ par exemple) ou de chaînes de caractères c aractères (pour les caractè caractères res d’« d’« échappement échappement »)  Mais on peut aussi utiliser pour cela la syntaxe (un peu peu lour lourde) de) « SQL Escape Escape » (voir plus loin) loin)  Ils évitent l'injection de code SQL R. Grin

'

'

JDBC

'

'

page 55





Comme les accès réseau auxles bases de données ralentissent les applications, procédures stockées permettent souvent d’améliorer les performances  Mais elles nuisent aussi souvent à la portabilité des applications R. Grin

Exemple de procédure stockée (Oracle) create or replace create replace proced procedure ure augmen augmenter ter (unDept (unDep t in intege integer, r, pourcentage pourcentage in number, number, cout out number) is  begin select sum(sal) * pourcentage / 100 into into cou out t fro m em p wher where e dept dept = u unD nDep ept; t; update emp set sal = sal * (1 + pourcentage / 100) wher where e dept dept = u unD nDep ept; t; end; R. Grin

JDBC

page 57

Les procédures stockées permettent non seulement de précompiler des ordres SQL mais aussi de les regrouper 

La syntaxe de l'appel des procédures stockées n'est pas standardisée ; elle diffère suivant les SGBD  JDBC utilise sa propre syntaxe pour pallier ce problème : si la procédure renvoie une valeur : Le driver { ? = call nom-procédure(?, ?,...) ?,...) } traduira si elle ne renvoie aucune valeur : dans la { call nom-procédure(?, ?,...) } syntaxe du SGBD si on ne lui passe aucun paramètre : { call nom-procédu nom-procédure re }

pa ge 56

Création d'une procédure stockée Les procédures stockées sont associées aux instances de l'interface l'interface CallableStatement CallableStatement qui hérite de l'interface PreparedStatement  La création d'une instance de CallableStatement se fait par l'appel de la méthode prepareCall de la classe Connection  On passe à cette méthode une chaîne chaîne de caractères qui décrit comment sera appelée la procédure stockée, et si la procédure renvoie une valeur ou non 

R. Grin

Syntaxe pour les procédures stockées 

JDBC

JDBC

pa ge 58

Exemple Call Callab ableS leSta tate teme ment nt cstm cstmt t = conn.prepareCall("{? = call augmenter(?,?)}");

n

n

n

R. Grin

JDBC

page 59

R. Grin

JDBC

pa ge 60

10

 

Lancement d'une procédure stockée L'appel de la procédure L'appel procédure est précédé précédé du passag passage e à la pro procéd cédure ure des par paramè amètre tress « in » et « in/out in/out » par les méthodes setXXX() (idem requêtes paramétrées)  On doit doit indiquer indiquer le type ddes es para paramètre mètress « out » et « in/ou in/outt » par la m métho éthode de reg register isterOutPa OutParamete rameter() r()  Ensuite on lance la procédure par une des méthodes executeQuery(), executeUpdate() ou execute(), suivant le type des commandes SQL que la procédure contient c ontient  On récu récupèr pèree le less pa param ramètr ètres es « out » et « in/out in/out » par les méthodes getXXX() (idem requêtes paramétrées) 

R. Grin

JDBC

page 61

Utilisation d'une procédure stockée CallableS Callab leStat tatemen ement t csm csmt t = con conn.pr n.prepar epareCa eCall( ll( "{ call augmenter(?, ?, ?) }"); // 2 chiffres après la virgule pour 3ème paramètre

csmt.registerOutParameter(3, Types.DECIMAL, 2); // Augmentation de 2,5 % des des salaires du dept 10

csmt.setInt(1, 10); csmt.setDouble(2, 2.5); csmt.executeQuery(); // ou execute() double cout = csmt.getDouble(3); System.out.println("Cout total augmentation : " + cout); R. Grin

Procédures stockées contenant 

plusieurs ordres SQL Une procédure stockée peut contenir plusieurs



On peut ne pas savoir quels ordres SQL sont contenus dans une procédure stockée  Dans ce cas, on utilise le fait que n n

Statement

n

Ainsi, si elle contient 2 ordres SELECT, on récupère le 1er ResultSet par getResultSet ; on passe à la 2ème requête par getMoreResults et on récupère son ResultSet par getResultSet

R. Grin

JDBC

page 63

Schéma de code

JDBC



execute renvoie execute renvoie true true si le 1er  résultat est un ResultSet getMoreResults renvoie true si le résultat suivant est un ResultSet getUpdateCount() : renvoie le nombre de lignes modifiées, ou -1 s'il n'y a plus de résultat (ou si le résultat est un ResultSet)

On peut exécuter tous les ordres dans une boucle dont la condition de fin est !getMoreResults() && getUpdateCount() == -1

R. Grin

JDBC

pa ge 64

Renvoyer un ResultSet d’une procédure stockée avec Oracle

 boolean retval = cstmt.execute(); do { if (retval (retval == false) false) { // pas un ResultSet ResultSet int coun count t = cstmt.getU cstmt.getUpdate pdateCoun Count(); t(); if (count == -1) break; // c’est fini ! else { // tra traite ite l’ordre l’ordre SQ SQL L . . . } } else else { // Res Result ultSet Set ResultSet Resul tSet rs = cstmt.getResul cstmt.getResultSet( tSet(); ); . . . // traite le ResultSet } retval retva l = cstmt.get cstmt.getMoreR MoreResult esults(); s(); while while (true) (true); ; R. Grin

pa ge 62

Ordre SQL quelconque

ordres SQL de divers types  Pour retrouver tous les résultats de ces ordres (ResultSet ou nombre de lignes modifiées), on utilise la méthode getMoreResults() de la classe 

JDBC

Attention, les 4 transparents qui suivent sur ce sujet sont particuliers particuliers à Oracle ; consultez consultez le manuel de votre SGBD si vous travaillez avec un autre SGBD  Il faut faut utili utiliser ser le le type type « ref cursor » d’Ora d’Oracle cle eett des extensions JDBC fournies avec le driver distribué par Oracle  Le curseur Oracle Oracle sera fermé quand l’instance de CallableStatement sera fermée 

page 65

R. Grin

JDBC

pa ge 66

11

 

Créer le type référence de curseur

Fonction qui renvoie un curseur 1.

Il faut Créer un type pour la référence de curseur qu’on va renvoyer 

2.

Créer la fonction qui renvoie la référence de curseur 



R. Grin

JDBC

Créer un nom de type pour la référence de curseur qu’on va renvoyer   Pour utiliser ensuite le type, il faut le créer dans un



paquetage create or :rep create replac lace e pack package age Typ Types es AS type curseur curseur_type _type is ref cursor cursor; ; end Types;

page 67

R. Grin

Call Callab able leSt Stat atem ement ent cstm cstmt t = conn.prepareCall("{ ? = call list(?) }"); cstmt.setInt(2, 10); cstmt.registerOutParameter(1, OracleTypes.CURSOR); cstmt.execute(); Resul ResultS tSet et rs = ((OracleCallableStatement)cstmt) .getCursor(1); while whil e (rs (rs.ne .next( xt()) )) { System.out.println(rs.getString("nomE") + ";" + rs.getInt("dept")); }

create crea te or rep replac lace e functio func tion n listde listdept( pt(num num intege integer) r) return Types.curseur_type is empcursor empcur sor Types.curseur Types.curseur_type; _type;  begin open empcurseur for select dept, nomE from emp wh e er r e dept = num; return empcurseur; end; JDBC

pa ge 68

Utiliser la fonction dans JDBC

Créer la fonction

R. Grin

JDBC

page 69

R. Grin

JDBC

pa ge 70

Fermer les ressources

Les resso ressources urces à fermer

Toutes les ressources JDBC doivent être fermées dès qu’elles ne sont plus utilisées  Le plus souvent la fermeture doit se faire dans un bloc finally pour qu’elle ait lieu quel que soit le déroulement des opérations (avec ou sans erreurs)  Les ressources sont automatiquement fermées par le ramasse-miettes mais il faut les fermer explicitement (on ne sait quand/si il va être lancé)

: leur fermeture est indispensable car c’est la ressource la plus coûteuse ; si on utilise un pool de connexions, la fermeture rend la connexion au pool  Statement , et les sous-interfaces PreparedStatement et CallableStatement  ResultSet : il est est automatiquement automatiquement fermé lorsque le statement qui l’a l’a engendr engendréé est fermé ou réexécuté, ou utilisé pour retrouver le prochain résultat (getMoreResults )

R. Grin

R. Grin



JDBC

page 71



Connection

JDBC

pa ge 72

12

 

Syntaxe spéciale de JDBC

Les Meta données

(« SQL Escape syntax ») 

Comme avec les procédures stockées, JDBC a une syntaxe spéciale pour ne pas dépendre de particularités des différents SGBD : n n n

dat dates es : {d '2000-10-5'} appels de fonctions fonctions : {fn concat("Hot", concat("Hot", "Java")} "Java")}  jointures externes : con.createStatement("SELECT * FROM" + " {oj {oj EMP RIG RIGHT HT OUTER OUTER JOIN DEPT" + " ON EMP.DEPT = DEPT.DEPT}");

n



JDBC permet de récupérer des informations sur le type de données que l'on vient de récupérer r écupérer par un SELECT (interface ResultSetMetaData),



mais aussiDatabaseMetaData) sur la base de données elle-même (interface  Les données que l'on peut récupérer avec DatabaseMetaData dépendent du SGBD avec lequel on travaille

caractère caract ère d’échappeme d’échappement nt utilisé par LIKE :

 WHERE Id LIKE '_%\\' {escape '\'} R. Grin

JDBC

page 73

R. Grin

JDBC

pa ge 74

DatabaseMetaData

ResultSetMetaData

 private DatabaseMetaData metaData;  private java.awt.List listTables = new List(10);

Re Resu sult ltSe Set t rs = stmt.executeQuery("SELECT * FROM emp");

. . .

Result Res ultSetM SetMetaD etaData ata rsmd rsmd = rs.getM rs.getMeta etaDat Data() a(); ;

 metaData = conn.getMetaData();

int nbColo nbColonnes nnes = rsmd.ge rsmd.getCol tColumnC umnCoun ount() t(); ;

String[] types = { "TABLE", "VIEW" };

for (int (int i = 1; i < <= = nbColonnes; nbColonnes; i++) i++) { String typeColonne typeColonne = rsmd.getColumnTy rsmd.getColumnTypeName( peName(i); i); String nomColonn nomColonne e = rsmd.getColumn rsmd.getColumnName(i Name(i); ); System.out.println("Colonne " + i + " de nom " + nomColo nomColonne nne + " de type type "

Resu Result ltSe Set t rs =  metaData.getTables(null, null, "%", types); String nomTables; while whi le (rs (rs.ne .next() xt()) ) { nomTable nomTab le = rs.get rs.getString String(3); (3);

+ typeColonne);

listTables.add(nomTable);

}

Joker pour noms des tables et vues

} R. Grin

JDBC

page 75

R. Grin

JDBC

pa ge 76

Ordre Or dre SQ SQLL « dy dyna nami miqu ques es » Au moment où il écrit le programme, le programmeur peut ne pas connaître, le type SQL des valeurs insérées ou retrouvées dans la base de données  Pour cela, JDBC a prévu les méthodes getObject() et setObject() qui effectuent des conversions automatiques (ou non) entre les types Java et SQL



R. Grin

JDBC

page 77

13

Sponsor Documents

Or use your account on DocShare.tips

Hide

Forgot your password?

Or register your new account on DocShare.tips

Hide

Lost your password? Please enter your email address. You will receive a link to create a new password.

Back to log-in

Close