Vous êtes sur la page 1sur 13

Prsentation JDBC de base

Universit de Nice - Sophia Antipolis Richard Grin


Version 3.1 16/8/07

JDBC (Java Data Base Connectivity) permet l'accs des bases de donnes avec le langage SQL, depuis un programme en Java Il est fourni par le paquetage java.sql LAPI JDBC est presque totalement indpendante des SGBDs (quelques mthodes ne peuvent tre utilises quavec certains SGBDs mais ne doivent tre utilises quen cas de ncessit imprieuse pour amliorer les performances)
R. Grin JDBC page 2

Versions de SQL supportes


Les premires versions de JDBC supportent le standard SQL-2 Entry Level JDBC 2 et 3 offrent en plus des fonctionnalits de SQL3 Pour des raisons d'efficacit un driver peut utiliser les possibilits particulires d'un SGBD (c'est permis par JDBC), mais au dtriment de la portabilit JDBC 4 accompagne Java 6 ; il utilise les annotations et apporte plus de facilits pour lcriture du code
R. Grin JDBC page 3

Contenu de java.sql
Ce paquetage contient un grand nombre d'interfaces et quelques classes Les interfaces constituent linterface de programmation JDBC ne fournit pas les classes qui implantent les interfaces

R. Grin

JDBC

page 4

Drivers
Pour travailler avec un SGBD il faut disposer de classes qui implantent les interfaces de JDBC Un ensemble de telles classes est dsign sous le nom de driver JDBC Les drivers dpendent du SGBD auquel ils permettent d'accder Tous les SGBD importants du march ont un (et mme plusieurs) driver JDBC, fourni par l'diteur du SGBD ou par des diteurs de logiciels indpendants
R. Grin JDBC page 5

Types de drivers
Type 1 : pont JDBC-ODBC Type 2 : driver qui fait appel des fonctions 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 middleware Type 4 : driver crit entirement en Java, qui utilise le protocole rseau du SGBD

R. Grin

JDBC

page 6

Type 1 : pont JDBC-ODBC


Application Java Driver JDBC Driver ODBC Les mthodes du driver JDBC font appel des fonctions en langage C d'un driver ODBC (en Java) (pas en Java)

Type 2 : utilise une API native


Application Java Partie en Java Partie native (en Java) (pas en Java)

Les mthodes du driver JDBC font appel des fonctions d'une API du SGBD crite dans un autre langage que Java

Driver

Protocole du SGBD

SGBD
R. Grin JDBC page 7 R. Grin JDBC

SGBD
page 8

Type 3 : accs un serveur middleware


Application Java

Type 4 : 100 % Java avec accs direct au SGBD


Application Java Driver en Java

Les mthodes du driver JDBC se connectent par socket au serveur middleware et lui envoient les requtes SQL ; le serveur middleware les traitent en se connectant au SGBD

Driver en Java Protocole du serveur middleware Serveur middleware

Les mthodes du driver JDBC utilisent des sockets pour dialoguer avec le SGBD selon son protocole rseau
SGBD

Protocole du SGBD

SGBD
R. Grin JDBC page 9 R. Grin JDBC

page 10

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 scurit, une applet untrusted (qui fonctionne dans le bac sable ; voir cours sur la scurit) ne peut changer des donnes par sockets qu'avec la machine d'o elle provient, ce qui implique des contraintes avec les drivers de type 3 et 4
R. Grin JDBC page 11

Driver de type 3 et applet untrusted


Le serveur middleware doit tre sur la mme machine que le serveur HTTP Code Java Applet Driver en Java connexion par socket Serveur HTTP Serveur middleware

SGBD
R. Grin JDBC page 12

Driver de type 4 et applet untrusted


Code Java Le serveur HTTP doit tre sur la mme machine que le SGBD Driver en Java Applet

Travailler avec JDBC


connexion par socket

Serveur HTTP

SGBD
JDBC page 13 R. Grin JDBC page 14

R. Grin

Pour utiliser JDBC


A lexcution, 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

Dans les classes qui utilisent JDBC


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

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

et lapplication sera lance par la commande


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

Inutile avec JDBC 4 !

R. Grin

JDBC

page 15

R. Grin

JDBC

page 16

tapes du travail avec une base de donnes avec JDBC


1. Ouvrir une connexion (Connection) 2. Crer des instructions SQL (Statement, PreparedStatement ou CallableStatement) 3. Lancer l'excution 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 page 18

Avertissement
Nous tudierons tout d'abord les classes et mthodes de base de JDBC Des nouvelles possibilits de JDBC 2 et 3, en particulier celles qui sont lies SQL3, seront abordes dans les parties JDBC avanc et JDBC et objet-relationnel Dans la suite du cours on utilise des raccourcis tels que instance de Connection Comme Connection est une interface, il faut traduire par instance dune classe qui implmente Connection

R. Grin

JDBC

page 19

R. Grin

JDBC

page 20

Interfaces principales
Driver : renvoie une instance de Connection Connection : connexion une base Statement : ordre SQL PreparedStatement : ordre SQL paramtr CallableStatement : procdure stocke sur le SGBD ResultSet : lignes rcupres par un ordre SELECT ResultSetMetaData : description des lignes rcupres par un SELECT DatabaseMetaData : informations sur la base de donnes
R. Grin JDBC page 21

Classes principales
DriverManager : gre les drivers, lance les connexions aux bases Date : date SQL Time : heures, minutes, secondes SQL TimeStamp : date et heure, avec une prcision la microseconde Types : constantes pour dsigner les types SQL (pour les conversions avec les types Java)

R. Grin

JDBC

page 22

Exceptions
SQLException : erreurs SQL SQLWarning : avertissements SQL (classe fille de SQLException) ; le mcanisme de rcupration des avertissements est tudi plus loin DataTruncation : avertit quand une valeur est tronque lors d'un transfert entre Java et le SGBD (classe fille de SQLWarning)

Exceptions de JDBC 4 (1)


SQLException a 3 sous-classes pour distinguer diffrents types dexception n SQLNonTransientException : le problme ne peut tre rsolu sans une action externe ; inutile de ressayer la mme action sans rien faire de spcial n SQLTransientException : le problme peut avoir t rsolu si on attend un peu avant de ressayer n SQLRecoverableException : lapplication peut rsoudre le problme en excutant une certaine action
R. Grin JDBC page 24

R. Grin

JDBC

page 23

Exceptions de JDBC 4 (2)


Classes filles de SQLNonTransientException : SQLDataException, SQLFeatureNotSupportedException, SQLIntegrityConstraintViolationException, SQLInvalidAuthorizationException, SQLNonTransientConnectionException, SQLSyntaxErrorException Classes filles de SQLTransientException : SQLTimeoutException, SQLTransactionRollbackException, SQLTransientConnectionException
R. Grin JDBC page 25

Chanage des exceptions


Une requte SQL peut provoquer plusieurs exceptions On peut obtenir la prochaine exception par la mthode getNextException() Une exception peut avoir une cause ; on l'obtient par la mthode getCause() Toutes ces exceptions peuvent tre parcourues par une boucle for-each :
catch(SQLException ex) { for (Throwable e : ex) { }
R. Grin JDBC page 26

Interface Driver
La mthode connect() de Driver prend en paramtre un URL et renvoie une instance de l'interface Connection Cette instance de Connection permettra de lancer des requtes vers le SGBD connect renvoie null si le driver ne convient pas pour se connecter la base dsigne par l'URL

URL d'une base de donnes


Un URL pour une base de donnes est de la forme : jdbc:sous-protocole:base de donne Par exemple, pour Oracle : jdbc:oracle:thin:@sirocco.unice.fr:1521:INFO n oracle:thin est le sous-protocole (driver thin ; Oracle fournit aussi un autre type de driver) n @sirocco.unice.fr:1521:INFO dsigne la base de donnes INFO situe sur la machine sirocco (le serveur du SGBD coute sur le port 1521) La forme exacte des parties sous-protocole et base de donnes dpend du SGBD cible
R. Grin JDBC page 28

Utilise par DriverManager ; pas visible par lutilisateur de lAPI


R. Grin JDBC page 27

Gestionnaire de drivers
La classe DriverManager gre les drivers (instances de Driver) disponibles pour les diffrents SGBD utiliss par le programme Java Pour qu'un driver soit utilisable, on doit charger sa classe en mmoire :
Class.forName("oracle.jdbc.OracleDriver");

JDBC 4 et le driver
JDBC 4 utilise un autre mcanisme pour charger le driver : il suffit d'indiquer le nom de la classe du driver dans un fichier META-INF/services/java.sql.Driver distribu avec le driver JDBC Il est alors inutile dappeler la mthode Class.forName

La classe cre alors une instance d'elle mme et enregistre cette instance auprs de la classe DriverManager
R. Grin JDBC page 29

R. Grin

JDBC

page 30

Obtenir une connexion


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

Connexions et threads
Les connexions sont des ressources coteuses, et surtout longues obtenir On peut donc tre tent de les rutiliser dans plusieurs threads diffrents Mais, attention, les connexions ne peuvent tre partages par plusieurs threads la place, utiliser les pools de connexions fournis avec les sources de donnes (tudies dans une autre partie du cours)
R. Grin JDBC page 32

La classe DriverManager s'adresse tour de rle tous les drivers qui se sont enregistrs (mthode connect), jusqu' ce qu'un driver lui fournisse une connexion (ne renvoie pas null)
R. Grin JDBC page 31

Transactions
Par dfaut la connexion est en auto-commit : un commit est automatiquement lanc aprs chaque ordre SQL qui modifie la base Le plus souvent il faut enlever l'auto-commit : 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

Niveau disolation
Le niveau disolation dune transaction peut tre modifi :
conn.setTransactionIsolation( Connection.TRANSACTION_SERIALIZABLE);

JDBC

page 34

Instruction SQL simple


Instance de l'interface Statement La cration est effectue par la mthode createStatement() de Connection :
Statement stmt = connexion.createStatement();

Excution de linstruction SQL simple


La mthode appeler dpend de la nature de l'ordre SQL que lon veut excuter : n consultation (select) : executeQuery() renvoie un ResultSet pour rcuprer les lignes une une n modification des donnes (update, insert, delete) ou ordres DDL (create table,) : executeUpdate() renvoie le nombre de lignes modifies n si on ne connat pas l'excution la nature de l'ordre SQL excuter ou si l'ordre peut renvoyer plusieurs rsultats : execute()
R. Grin JDBC page 36

R. Grin

JDBC

page 35

Consultation des donnes (SELECT)


Statement stmt = conn.createStatement(); // rset contient les lignes renvoyes ResultSet rset = stmt.executeQuery("SELECT nomE FROM emp"); // On rcupre chaque ligne une une while (rset.next()) System.out.println (rset.getString(1)); // ou . . . (rset.getString("nomE")); stmt.close(); La premire colonne a le numro 1 Voir plus loin le transparent sur la R.fermeture des ressources Grin

Interface ResultSet
executeQuery() renvoie une instance de ResultSet ResultSet va permettre de parcourir toutes les lignes renvoyes par le select Au dbut, ResultSet est positionn avant la premire ligne et il faut donc commencer par le faire avancer la premire ligne en appelant la mthode next() Cette mthode permet de passer la ligne suivante ; elle renvoie true si cette ligne suivante existe et false sinon
R. Grin JDBC page 38

JDBC

page 37

Interface ResultSet
Quand ResultSet est positionn sur une ligne les mthodes getXXX permettent de rcuprer les valeurs des colonnes de la ligne : n getXXX(int numroColonne) n getXXX(String nomColonne) (nom simple dune
colonne, pas prfix par un nom de table ; dans le cas dune jointure utiliser un alias de colonne)

ResultSet - performances
Quand le rseau est lent et que lon veut rcuprer de nombreuses lignes, il est parfois possible damliorer sensiblement les performances en modifiant le nombre de lignes rcupres chaque fois par le ResultSet (il faut effectuer des tests pour chaque cas) Pour cela, on utilise la mthode setFetchSize de Statement Cest seulement une indication quon donne au driver ; il nest pas oblig den tenir compte
R. Grin JDBC page 40

XXX dsigne le type Java de la valeur que l'on va rcuprer, par exemple String, Int ou Double Par exemple, getInt renvoie un int
R. Grin JDBC page 39

Types JDBC/SQL
Tous les SGBD n'ont pas les mmes types SQL ; mme les types de base peuvent prsenter des diffrences importantes Pour cacher ces diffrences, JDBC dfinit ses propres types SQL dans la classe Types, sous forme de constantes nommes Ils sont utiliss par les programmeurs quand ils doivent prciser 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

Types JDBC/SQL (classe Types)


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

page 42

Correspondances entre types Java et SQL


Il reste le problme de la correspondance entre les types Java et les types SQL Dans un programme JDBC, les mthodes getXXX, setXXX servent prciser cette correspondance Par exemple, getString indique que lon veut rcuprer la donne SQL dans une String C'est le rle du driver particulier chaque SGBD de faire les traductions correspondantes ; une exception peut tre lance si a nest pas possible
R. Grin JDBC page 43

Correspondances avec getXXX()


On a une grande latitude ; ainsi, presque tous les types SQL peuvent tre retrouvs par getString() Cependant, des mthodes sont recommandes ; voici des exemples :
n

n n n

CHAR et VARCHAR : getString, LONGVARCHAR : getAsciiStream et getCharacterStream BINARY et VARBINARY : getBytes, LONGVARBINARY : getBinaryStream REAL : getFloat, DOUBLE et FLOAT : getDouble DECIMAL et NUMERIC : getBigDecimal DATE : getDate, TIME : getTime, TIMESTAMP : getTimestamp
JDBC page 44

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 donnes Cette classe hrite de la classe java.util.Date Elle correspond un temps en millisecondes Normalement les dates SQL ne contiennent pas dindication sur lheure dans la journe ; il faut utiliser les types SQL TIME et TIMESTAMP pour lheure dans la journe Pour passer de java.util.Date java.sql.Date, utiliser la mthode getTime()
R. Grin JDBC page 45

Exemple
Pour passer de java.util.Date java.sql.Date, utiliser la mthode getTime():
java.util.Date date = new java.util.Date(); java.sql.Date dateSQL = new java.sql.Date(date.getTime()); java.sql.Time time = new Time(date.getTime()); java.sql.Timestamp time = new Timestamp(date.getTime());

R. Grin

JDBC

page 46

Manipulation des dates


Un petit rappel sur les dates en Java : n mise en forme avec la classe java.text.DateFormat
n

Valeur NULL
Statement stmt = conn.createStatement(); ResultSet rset = stmt.executeQuery( "SELECT nomE, comm FROM emp"); while (rset.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 commission"); }
page 47 R. Grin JDBC page 48

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

Voir le cours sur les dates dans le support Complments divers

R. Grin

JDBC

Modification des donnes (INSERT, UPDATE, DELETE)


Statement stmt = conn.createStatement(); String ville = "NICE"; int nbLignesModifiees = stmt.executeUpdate( "INSERT INTO dept (dept, nomD, lieu) " + "VALUES (70, 'DIRECTION'," + "'" + ville + "')"); N'oubliez pas stmt.close(); l'espace !

Instruction SQL paramtre


La plupart des SGBD (dont Oracle) peuvent n'analyser qu'une seule fois une requte excute un grand nombre de fois durant une connexion JDBC permet de profiter de ce type de fonctionnalit par l'utilisation de requtes paramtres ou de procdures stockes Les requtes paramtres sont associes aux instances de l'interface PreparedStatement qui hrite de l'interface Statement
R. Grin JDBC page 50

R. Grin

JDBC

page 49

Cration d'une requte paramtre


PreparedStatement pstmt = conn.prepareStatement("UPDATE emp SET sal = ?" + " WHERE nome = ?");

Requte paramtre Valeurs des paramtres


Les valeurs des paramtres sont donnes par les mthodes setXXX(n, valeur) On choisit la mthode setXXX suivant le type Java de la valeur que l'on veut mettre dans la base de donnes C'est au programmeur de passer une valeur Java du bon type la mthode setXXX Le driver JDBC fait la conversion dans le bon format pour le SGBD
R. Grin JDBC page 52

Les "?" indiquent les emplacements des paramtres Cette requte pourra tre excutes avec plusieurs couples de valeurs : (2500, DUPOND), (3000, DURAND), etc.

R. Grin

JDBC

page 51

Requte paramtre - Exemple


PreparedStatement pstmt = conn.prepareStatement( "UPDATE emp SET sal = ? " + "WHERE nomE = ?"); commence 1 et pas 0 for (int i=0; i<10; i++) { pstmt.setDouble(1,employe[i].getSalaire()); pstmt.setString(2, employe[i].getNom()); pstmt.executeUpdate(); }

Requte paramtre - NULL


Pour passer la valeur NULL la base de donne, on peut n utiliser la mthode setNull(n, type) (type de la classe Types) n ou passer la valeur Java null si la mthode setXXX() attend un objet en paramtre

R. Grin

JDBC

page 53

R. Grin

JDBC

page 54

Avantages des PreparedStatement


Leur traitement est plus rapide sils sont utiliss plusieurs fois avec plusieurs paramtres Ils amliorent aussi la portabilit car les mthodes setXXX grent les diffrences entre SGBD En effet, les SGBD nutilisent pas tous les mmes formats de date ('JJ/MM/AA' ou 'AAAA-MM-JJ' par exemple) ou de chanes de caractres (pour les caractres d chappement ) Mais on peut aussi utiliser pour cela la syntaxe (un peu lourde) SQL Escape (voir plus loin) Ils vitent l'injection de code SQL
R. Grin JDBC page 55

Procdures stockes
Les procdures stockes permettent non seulement de prcompiler des ordres SQL mais aussi de les regrouper Comme les accs rseau aux bases de donnes ralentissent les applications, les procdures stockes permettent souvent damliorer les performances Mais elles nuisent aussi souvent la portabilit des applications
R. Grin JDBC page 56

Exemple de procdure stocke (Oracle)


create or replace procedure augmenter (unDept in integer, pourcentage in number, cout out number) is begin select sum(sal) * pourcentage / 100 into cout from emp where dept = unDept; update emp set sal = sal * (1 + pourcentage / 100) where dept = unDept; end;
R. Grin JDBC page 57

Cration d'une procdure stocke


Les procdures stockes sont associes aux instances de l'interface CallableStatement qui hrite de l'interface PreparedStatement La cration d'une instance de CallableStatement se fait par l'appel de la mthode prepareCall de la classe Connection On passe cette mthode une chane de caractres qui dcrit comment sera appele la procdure stocke, et si la procdure renvoie une valeur ou non
R. Grin JDBC page 58

Syntaxe pour les procdures stockes


La syntaxe de l'appel des procdures stockes n'est pas standardise ; elle diffre suivant les SGBD JDBC utilise sa propre syntaxe pour pallier ce problme : n si la procdure renvoie une valeur : Le driver { ? = call nom-procdure(?, ?,...) } traduira n si elle ne renvoie aucune valeur : dans la { call nom-procdure(?, ?,...) } syntaxe du SGBD n si on ne lui passe aucun paramtre : { call nom-procdure }
R. Grin JDBC page 59

Exemple
CallableStatement cstmt = conn.prepareCall("{? = call augmenter(?,?)}");

R. Grin

JDBC

page 60

10

Lancement d'une procdure stocke


L'appel de la procdure est prcd du passage la procdure des paramtres in et in/out par les mthodes setXXX() (idem requtes paramtres) On doit indiquer le type des paramtres out et in/out par la mthode registerOutParameter() Ensuite on lance la procdure par une des mthodes executeQuery(), executeUpdate() ou execute(), suivant le type des commandes SQL que la procdure contient On rcupre les paramtres out et in/out par les mthodes getXXX() (idem requtes paramtres)
R. Grin JDBC page 61

Utilisation d'une procdure stocke


CallableStatement csmt = conn.prepareCall( "{ call augmenter(?, ?, ?) }");
// 2 chiffres aprs la virgule pour 3me 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(); // ou execute() double cout = csmt.getDouble(3); System.out.println("Cout total augmentation : " + cout);
R. Grin JDBC page 62

Procdures stockes contenant plusieurs ordres SQL


Une procdure stocke peut contenir plusieurs ordres SQL de divers types Pour retrouver tous les rsultats de ces ordres (ResultSet ou nombre de lignes modifies), on utilise la mthode getMoreResults() de la classe Statement Ainsi, si elle contient 2 ordres SELECT, on rcupre le 1er ResultSet par getResultSet ; on passe la 2me requte par getMoreResults et on rcupre son ResultSet par getResultSet
R. Grin JDBC page 63

Ordre SQL quelconque


On peut ne pas savoir quels ordres SQL sont contenus dans une procdure stocke Dans ce cas, on utilise le fait que
n n

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

On peut excuter tous les ordres dans une boucle dont la condition de fin est
!getMoreResults() && getUpdateCount() == -1
R. Grin JDBC page 64

Schma de code
boolean retval = cstmt.execute(); do { if (retval == false) { // pas un ResultSet int count = cstmt.getUpdateCount(); if (count == -1) break; // cest fini ! else { // traite lordre SQL . . . } } else { // ResultSet ResultSet rs = cstmt.getResultSet(); . . . // traite le ResultSet } retval = cstmt.getMoreResults(); while (true);
R. Grin JDBC page 65

Renvoyer un ResultSet dune procdure stocke avec Oracle


Attention, les 4 transparents qui suivent sur ce sujet sont particuliers Oracle ; consultez le manuel de votre SGBD si vous travaillez avec un autre SGBD Il faut utiliser le type ref cursor dOracle et des extensions JDBC fournies avec le driver distribu par Oracle Le curseur Oracle sera ferm quand linstance de CallableStatement sera ferme
R. Grin JDBC page 66

11

Fonction qui renvoie un curseur


1. 2.

Crer le type rfrence de curseur


Crer un nom de type pour la rfrence de curseur quon va renvoyer Pour utiliser ensuite le type, il faut le crer dans un paquetage :
create or replace package Types AS type curseur_type is ref cursor; end Types;

Il faut Crer un type pour la rfrence de curseur quon va renvoyer Crer la fonction qui renvoie la rfrence de curseur

R. Grin

JDBC

page 67

R. Grin

JDBC

page 68

Crer la fonction
create or replace function listdept(num integer) return Types.curseur_type is empcursor Types.curseur_type; begin open empcurseur for select dept, nomE from emp where dept = num; return empcurseur; end;
R. Grin JDBC page 69

Utiliser la fonction dans JDBC


CallableStatement cstmt = conn.prepareCall("{ ? = call list(?) }"); cstmt.setInt(2, 10); cstmt.registerOutParameter(1, OracleTypes.CURSOR); cstmt.execute(); ResultSet rs = ((OracleCallableStatement)cstmt) .getCursor(1); while (rs.next()) { System.out.println(rs.getString("nomE") + ";" + rs.getInt("dept")); }
R. Grin JDBC page 70

Fermer les ressources


Toutes les ressources JDBC doivent tre fermes ds quelles ne sont plus utilises Le plus souvent la fermeture doit se faire dans un bloc finally pour quelle ait lieu quel que soit le droulement des oprations (avec ou sans erreurs) Les ressources sont automatiquement fermes par le ramasse-miettes mais il faut les fermer explicitement (on ne sait quand/si il va tre lanc)
R. Grin JDBC page 71

Les ressources fermer


Connection : leur fermeture est indispensable car cest la ressource la plus coteuse ; 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 automatiquement ferm lorsque le statement qui la engendr est ferm ou rexcut, ou utilis pour retrouver le prochain rsultat (getMoreResults)
R. Grin JDBC page 72

12

Syntaxe spciale de JDBC


( SQL Escape syntax )
Comme avec les procdures stockes, JDBC a une syntaxe spciale pour ne pas dpendre de particularits des diffrents SGBD :
n n n

Les Meta donnes


JDBC permet de rcuprer des informations sur le type de donnes que l'on vient de rcuprer par un SELECT (interface ResultSetMetaData), mais aussi sur la base de donnes elle-mme (interface DatabaseMetaData) Les donnes que l'on peut rcuprer avec DatabaseMetaData dpendent du SGBD avec lequel on travaille

dates : {d '2000-10-5'} appels de fonctions : {fn concat("Hot", "Java")} jointures externes : con.createStatement("SELECT * FROM" + " {oj EMP RIGHT OUTER JOIN DEPT" + " ON EMP.DEPT = DEPT.DEPT}"); caractre dchappement utilis par LIKE : WHERE Id LIKE '_%\\' {escape '\'}
JDBC page 73

R. Grin

R. Grin

JDBC

page 74

ResultSetMetaData
ResultSet rs = stmt.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); }
R. Grin JDBC page 75

DatabaseMetaData
private DatabaseMetaData metaData; private java.awt.List listTables = new List(10); . . . metaData = conn.getMetaData(); String[] types = { "TABLE", "VIEW" }; ResultSet rs = metaData.getTables(null, null, "%", types); String nomTables; Joker pour while (rs.next()) { noms des nomTable = rs.getString(3); tables et vues listTables.add(nomTable); }
R. Grin JDBC page 76

Ordre SQL dynamiques


Au moment o il crit le programme, le programmeur peut ne pas connatre, le type SQL des valeurs insres ou retrouves dans la base de donnes Pour cela, JDBC a prvu les mthodes getObject() et setObject() qui effectuent des conversions automatiques (ou non) entre les types Java et SQL

R. Grin

JDBC

page 77

13