Professional Documents
Culture Documents
Bases de donnes
T.P.
Interaction JAVA - Bases de donnes
Introduction JDBC
Ce TP1 a pour but de vous initier JDBC la faon d'un tutoriel. Si vous souhaitez des complments, vous
pouvez consulter les documents suivants :
- Support de cours : http://nicolas.durand.perso.luminy.univmed.fr/pub/bd/tpjdbc/JDBC.pdf
- Site officiel de SUN : http://java.sun.com/javase/technologies/database/
L'API2 JDBC (Java DataBase Connectivity) permet aux applications JAVA de communiquer avec les
gestionnaires de bases de donnes dans un langage universel l'instar des pilotes ODBC (Open DataBase
Connectivity) dans le monde Windows. Les applications sont ainsi indpendantes de la base de donnes
utilise. L'utilisation d'un pilote JDBC rend possible trois points :
- Etablir une connexion avec une base de donnes,
- Envoyer des requtes SQL,
- Traiter les rsultats.
Nous utiliserons le SGBD ORACLE de l'cole.
Un exemple de programme utilisant JDBC se trouve en annexe. Ne vous inquitez pas si vous ne
comprenez pas le code de cet exemple ! Nous allons reprendre chaque tape dans le TP.
Lisez attentivement chaque partie et lancez-vous dans la programmation seulement pour les 6 exercices.
1) Prliminaire
Rcuprez le driver JDBC pour ORACLE l'adresse suivante :
http://nicolas.durand.perso.luminy.univmed.fr/pub/bd/tpjdbc/ojdbc14.jar
Avec le driver JDBC pour ORACLE, le nom de la classe qui l'implmente est "oracle.jdbc.OracleDriver"
Ainsi, vous devez charger le pilote avec cette ligne de code :
Class.forName("oracle.jdbc.OracleDriver");
Vous n'avez pas besoin de crer une instance du pilote et de le rfrencer avec DriverManager. Il suffit
d'appeler Class.forName qui le fera pour vous automatiquement. Si vous aviez crer votre propre
instance, vous creriez un duplicata inutile.
Une fois le pilote charg, vous tes prt pour crer une connexion avec un SGDB.
Cette tape est aussi trs simple. Le plus dur est de fournir la bonne URL.
Si vous utilisez un pilote JDBC dvelopp par un tiers, la documentation vous dira quel sous-protocole
utiliser, donc, que mettre aprs "jdbc:" dans l'URL JDBC.
Voici les paramtres connaitre pour formater cette URL de connexion JDBC :
le nom de la machine o s'excute le SGBD : pedaserv1.luminy.univmed.fr
le numro de port sur lequel le SGBD est l'coute : 1521
s'il y a un nom de base de donnes renseigner (ce n'est pas ntre cas) : test
le login : compten
le mot de passe : compten (ou celui qui vous avez choisi).
Ainsi :
String url = "jdbc:oracle:thin:@pedaserv1.luminy.univmed.fr:1521";
Connection conn = DriverManager.getConnection(url,"compten","compten");
Si un des pilotes que vous avez charg reconnat l'URL JDBC fournit dans la mthode
DriverManager.getConnection, ce pilote tablira une connexion avec le SGBD spcifi dans l'URL
JDBC. La classe DriverManager prend en charge tous les dtails afin d'tablir, pour vous, la connexion.
Si vous avez crit votre propre pilote, vous n'aurez probablement jamais utiliser des mthodes de
l'interface Driver, et la seule mthode dont vous aurez besoin est DriverManager.getConnection.
La connexion retourne par la mthode DriverManager.getConnection est une connexion ouverte, ce
qui vous permet de passer vos instructions SQL vers votre SGBD. Dans l'exemple prcdant, conn est une
connexion ouverte, et nous l'utilisons pour les exemples du TP.
Remarque importante : il faut librer les ressources. Une connexion doit tre ferme si elle n'est plus
utilise ( faire systmatiquement en fin de programme).
conn.close();
FO_ID
101
49
150
101
49
PRIX
7.99
8.99
9.99
8.99
9.99
VENTES
0
0
0
0
0
TOTAL
0
0
0
0
0
La colonne qui contient le nom du caf est NOM_CAFE, elle supporte des valeurs de type VARCHAR et a
un maximum de 32 caractres de long. Comme nous utiliserons un nom diffrent pour chaque type de caf
vendu, le nom identifiera un caf de faon unique, et pourra donc servir de cl primaire notre table. La
seconde colonne, FO_ID, contient un nombre qui identifie le fournisseur de caf, cette variable SQL est de
type INTEGER. La troisime colonne, appele PRIX, est de type FLOAT. La colonne appele VENTES
contient des valeurs de type INTEGER, et indique le nombre de livres de caf vendues durant la semaine.
La dernire colonne, TOTAL, contient un INTEGER qui donne le nombre de livres de caf vendues jusqu'
maintenant.
FOURNISSEURS, la seconde table, donne des informations pour chaque fournisseur :
FO_ID NOM_FO
101
Acme, Inc
49
Superior Coffee
The
High
150
Ground
RUE
99 Market Street
1 Party Place
VILLE
GroundVille
Mendocino
ETAT CODE_POSTAL
CA
95199
CA
95460
Meadows
CA
93966
La colonne FO_ID est la cl primaire dans la table FOURNISSEURS, elle identifie de faon unique chacun
des fournisseurs de caf. Notez que dans la table CAFES, FO_ID est une cl trangre qui rfrence
FO_ID de la table FOURNISSEURS.
L'instruction SQL qui suit, cre la table CAFES.
CREATE TABLE CAFES (
NOM_CAFE VARCHAR(32),
FO_ID INTEGER,
PRIX FLOAT,
VENTES INTEGER,
TOTAL INTEGER
)
Ce code ne se termine pas par une fin d'instruction. Le pilote que vous utilisez apportera automatiquement
le symbole qui mettra fin l'instruction.
Maintenant, mettons le code entre guillemet (pour en faire une chane de caractres) et assignons ce
String une variable creerTableCafes que nous utiliserons plus tard dans notre code JDBC.
Remarque : un String qui s'tend sur plus d'une ligne peut poser des problmes. Par consquent, coupez
en plusieurs lignes et concatnez les avec un "+".
String creerTableCafes = "CREATE TABLE CAFES ("
+ " NOM_CAFE VARCHAR(32), FO_ID INTEGER, PRIX FLOAT,"
+ " VENTES INTEGER, TOTAL INTEGER)";
Le type de donnes que nous avons utilis dans notre CREATE TABLE est le type SQL (aussi appel type
JDBC) gnrique qui est dfini dans java.sql.Types. Les SGBD utilisent gnralement ces types standards.
Avant de vous lancer dans votre premier programme JDBC, nous allons traverser les notions de base.
4.1 Crer une instruction JDBC
Un objet Statement est ce que votre instruction SQL envoie vers le SGBD. Vous crerez simplement un
objet Statement puis, l'excuterez, lui fournissant la mthode d'excution approprie avec l'instruction
SQL que vous voulez envoyer. Pour une instruction SELECT, la mthode utiliser est executeQuery.
Pour les instructions visant crer ou modifier des tables, la mthode est executeUpdate.
Vous devez avoir l'instance d'une connexion active pour crer un objet Statement. Dans l'exemple
suivant, nous utilisons notre objet Connection conn, pour crer l'objet Statement stmt :
Statement stmt = conn.createStatement();
A ce niveau, stmt existe, mais il n'a aucune instruction SQL passer au SGBD. Nous devrons la fournir
dans la mthode que nous utiliserons pour excuter stmt. Par exemple, dans le code suivant, nous
proposons executeUpdate avec l'instruction SQL :
stmt.executeUpdate(creerTableCafes);
Remarque importante : un statement doit tre ferme s'il n'est plus utilis.
stmt.close();
Le code suivant insre une ligne de donnes, Colombian dans la colonne NOM_CAFE, 101 dans FO_ID,
7.99 dans PRIX, 0 dans VENTES et 0 dans TOTAL. ("The Coffee Break" vient juste de commencer, c'est
pourquoi certaines valeurs sont misent 0). Comme nous l'avons fait pour crer des tables, nous allons
dclarer un objet Statement, et l'excuter en utilisant la mthode executeUpdate.
Statement stmt = conn.createStatement();
stmt.executeUpdate("INSERT INTO CAFES VALUES ('Colombian', 101, 7.99, 0, 0)");
Le code qui suit insre une deuxime ligne dans la table CAFES. Nous rutilisons l'objet Statement
stmt plutt que d'en crer un nouveau pour chaque excution.
stmt.executeUpdate("INSERT INTO CAFES"
+ " VALUES ('French_Roast', 49, 8.99, 0, 0)");
Les valeurs pour les lignes restantes peuvent tre insres comme il suit :
stmt.executeUpdate("INSERT
+ " VALUES
stmt.executeUpdate("INSERT
+ " VALUES
stmt.executeUpdate("INSERT
+ " VALUES
INTO CAFES"
('Espresso', 150, 9.99, 0, 0)");
INTO CAFES"
('Colombian_Decaf', 101, 8.99, 0, 0)");
INTO CAFES"
('French_Roast_Decaf', 49, 9.99, 0, 0)");
Exercice 1
Ecrivez un programme JAVA permettant de se connecter votre base de donnes ORACLE, de crer la
table CAFES et d'alimenter cette dernire.
N'oubliez pas de fermer les ressources la fin de votre programme.
FO_ID
101
49
150
101
49
PRIX
7.99
8.99
9.99
8.99
9.99
VENTES
0
0
0
0
0
TOTAL
0
0
0
0
0
Le rsultat ci-dessus est ce que vous devez voir sur votre terminal si vous avez entr la requte SQL
directement dans le systme de la base de donnes. Lorsque nous accderons une base de donnes au
travers d'une application JAVA, nous aurons besoin de prendre les rsultats, pour que nous puissions les
utiliser. Nous dcrivons comment faire dans la prochaine section.
5
Voyons maintenant plus prcisment comment la mthode getXXX fonctionne en examinant les deux
instructions getXXX dans ce code. Premirement, examinons getString.
String nom = rs.getString("NOM_CAFE");
6
La mthode getString est invoque sur l'objet ResultSet rs, donc getString doit accder aux
valeurs contenues dans la colonne NOM_CAFE de la ligne courante de rs. La valeur que getString
rapporte a t convertie du SQL VARCHAR, au String de JAVA, et a t assigne l'objet String
nom. La situation est la mme avec la mthode getFloat, l'exception prs, qu'il rapporte la valeur
contenue dans la colonne PRIX, qui est un FLOAT SQL, et la convertir en float de JAVA avant de
l'assigner la variable prix.
JDBC offre deux faons d'identifier une colonne dont une mthode getXXX prendra la valeur. Une des
faons est de donner le nom de la colonne, comme dans l'exemple ci-dessus, et la seconde, est de donner
l'indice de la colonne (numro de la colonne), o 1 dsigne la premire colonne, 2 la deuxime colonne et
ainsi de suite. Utiliser le numro de la colonne la place de son nom donne le code suivant :
String nom = rs.getString(1);
float prix = rs.getFloat(2);
La premire ligne de code prend la valeur de la premire colonne de la ligne courante de rs (colonne
NOM_CAFE), la convertie en String JAVA, et l'assigne nom. La deuxime ligne de code, prend la
valeur contenue dans la deuxime colonne de la ligne courante de rs, la convertie en float JAVA, et
l'assigne prix.
Notez que le nombre de la colonne rfre au numro de la colonne dans le resultset, pas dans la table
originale.
En rsum, JDBC vous autorise utiliser le nom de la colonne ou son numro comme argument dans une
mthode getXXX. Utiliser le numro de colonne est un peu plus pratique, mais dans certains cas, le nom de
la colonne est requis. En gnral, fournir le nom de la colonne est essentiellement quivalent fournir son
numro.
Grce la mthode getXXX de JDBC, vous pouvez alors accder aux diffrents types de donnes SQL. Par
exemple, la mthode getInt peut tre utilise pour accder aux types numriques, ou caractres. Mais il
est recommand de n'utiliser getInt que pour accder des donnes SQL de type INTEGER. Il ne peut
pas tre utilis pour rapporter des donnes de type BINARY, VARBINARY, LONGVARBINARY,
DATE, TIME ou TIMESTAMP.
Vous trouverez les types et les mthodes getXXX dans le support de cours la diapo 32, et aussi ici :
http://java.sun.com/docs/books/tutorial/jdbc/basics/retrievingTable.html
Remarque : un resultset peut tre ferm s'il n'est plus utilis : rs.close();
Utilisant l'instruction stmt, le code JDBC excute l'instruction SQL contenue dans updateString :
stmt.executeUpdate(updateString);
7
FO_ID
101
49
150
101
49
PRIX
7.99
8.99
9.99
8.99
9.99
VENTES
75
0
0
0
0
TOTAL
0
0
0
0
0
Notez que nous n'avons pas encore mis jour la colonne TOTAL, sa valeur est toujours 0.
Maintenant, slectionnons la ligne mise jour, rapportons la valeur dans les colonnes de NOM_CAFE et
de VENTES, et affichons ces valeurs :
String requete = "SELECT NOM_CAFE, VENTES FROM CAFES"
+ " WHERE NOM_CAFE LIKE 'Colombian'";
ResultSet rs = stmt.executeQuery(requete);
while(rs.next()) {
String s = rs.getString("NOM_CAFE");
int n = rs.getInt("VENTES");
System.out.println(n + " livres de" + s + " vendu cette semaine.");
}
a affichera :
75 livres de Colombian vendu cette semaine.
La clause WHERE limite la slection une seule ligne, il n'y avait qu'une seule ligne dans le ResultSet
rs, et donc une seule ligne a t affiche. Dans ce cas, il est possible d'crire le code sans la boucle while :
rs.next();
String s = rs.getString(1);
int n = rs.getInt(2);
System.out.println(n + " livres de " + s + " vendu cette semaine.");
Mme si il n'y a qu'un seul rsultat dans le resultset, vous devez utiliser la mthode next pour y accder.
Maintenant mettons jour la colonne TOTAL en ajoutant le montant hebdomadaire au total existant, et
affichons le nombre de livres vendues ce jour :
String updateString = "UPDATE CAFES"
+ " SET TOTAL = TOTAL + 75"
+ " WHERE NOM_CAFE LIKE 'Colombian'";
stmt.executeUpdate(updateString);
String query = "SELECT NOM_CAFE, TOTAL FROM CAFES"
+ " WHERE NOM_CAFE LIKE 'Colombian'";
ResultSet rs = stmt.executeQuery(query);
while(rs.next()) {
String s = rs.getString(1);
int n = rs.getInt(2);
System.out.println(n+" livres de " + s + " vendu jusqu' maintenant.");
}
8
Notez que dans cet exemple, nous utilisons l'indice de la colonne plutt que son nom, fournir l'indice 1
getString (la premire colonne du resultset est NOM_CAFE), et l'indice 2 getInt (la seconde
colonne du resultset est TOTAL). Il est important de faire la distinction entre l'indice d'une colonne dans la
table de la base de donnes comme oppose l'indice dans le resultset. Par exemple, TOTAL est la
cinquime colonne dans la table CAFES mais c'est la seconde colonne dans le rsultat gnr par la requte
dans l'exemple ci-dessus.
Exercice 2
Ecrivez un programme JAVA ralisant l'exemple final de la section 6.
La variable updateVentes contient maintenant une instruction SQL, "UPDATE CAFES SET VENTES =
? WHERE NOM_CAFE LIKE ?", qui a t envoye SGBD puis prcompile.
Comme vous pouvez le voir dans l'exemple, le premier argument donn la mthode setXXX est la
position du point d'interrogation, et le deuxime argument, la valeur par laquelle on veut le remplacer.
L'exemple suivant substitue le deuxime paramtre avec le string "Colombian".
updateVentes.setString(2, "Colombian");
Aprs que ces valeurs aient t dposes dans les deux paramtres d'entres, l'instruction SQL contenue
dans updateVentes sera quivalente l'instruction SQL dans l'objet String updateString que nous
avons utilis dans un des exemples prcdents. Les deux fragments de codes suivants font la mme chose :
Code 1 :
String updateString = "UPDATE CAFES SET VENTES = 75"
+ " WHERE NOM_CAFE LIKE 'Colombian'";
stmt.executeUpdate(updateString);
Code 2 :
PreparedStatement updateVentes =
conn.preparedStatement("UPDATE CAFES SET VENTES = ? WHERE NOM_CAFE LIKE ?");
updateVentes.setInt(1,75);
updateVentes.setString(2, "Colombian");
updateVentes.executeUpdate();
Nous avons utilis la mthode executeUpdate pour excuter les objets Statement stmt et
PreparedStatement updateVentes. Remarquez qu'aucun argument n'est fourni executeUpdate
quand ils sont utiliss pour excuter updateVentes. Et ceci est juste, car updateVentes contient dj
l'instruction SQL devant tre excute.
Prtez attention ces exemples, vous verrez pourquoi vous devrez utiliser un objet PreparedStatement
avec paramtres, plus qu'une simple instruction, et ce, mme si elle ncessite moins d'tapes.
Si vous mettez une ou deux fois jours la colonne VENTES, cela ne vaut pas la peine d'utiliser une
instruction SQL avec paramtres. Mais si vous la mettez souvent jours, il sera plus simple d'utiliser un
objet PreparedStatement, spcialement en situation o vous avez utiliser une boucle for ou une
boucle while pour dfinir un paramtre une succession de donnes. Nous allons voir un exemple plus tard
dans cette section.
Une fois qu'on a assign une valeur un paramtre, il retiendra la valeur jusqu' ce qu'elle soit rinitialise
avec une autre valeur, ou bien jusqu' ce que la mthode clearParameters soit appele. Utilisant l'objet
PrepareStatement updateVentes. Le code suivant illustre la rutilisation d'un preparedstatement
aprs avoir rinitialis la valeur de l'un des paramtres et en conservant la valeur de l'autre paramtre :
10
updateVentes.setInt(1, 100);
updateVentes.setString(2, "French_Roast");
updateVentes.executeUpdate();
//Change la valeur de VENTES la ligne French Roast pour la valeur 100
updateVentes.setString(2, "Espresso");
updateVentes.executeUpdate();
//Change la valeur de la colonne VENTES la ligne Espresso pour la valeur 100
//(le premier paramtre est rest 100, et le second paramtre est
//rinitialis par "Espresso")
Quand le propritaire dsire faire une mise jour sur les montants des ventes de la semaine suivante, il peut
utiliser ce code comme modle. Il ne lui reste plus qu' entrer de nouveaux montants de vente dans l'ordre
adquat dans le tableau VentesDeLaSemaine. Le nom du caf dans le tableau cafe reste constant, donc
il n'a pas besoin d'y apporter de modifications. (Dans une vraie application, les valeurs seraient
probablement entres par l'utilisateur plutt que d'tre initialises dans le tableau)
Exercice 3
Ecrivez un programme JAVA ralisant l'exemple prcdent (section 7.4).
11
La table CAFES a t mise jour en remplaant la valeur contenue dans la colonne VENTES de la ligne
Espresso par 50. La mise jour affecte une seule ligne dans la table, donc n est gal 1.
Quand la mthode executeUpdate est utilise pour excuter une instruction DDL, comme crer une
table, elle retourne la valeur 0. Dans le fragment de code suivant, qui excute une instruction DDL pour
crer la table CAFES, n recevra la valeur 0 :
int n = executeUpdate(createTableCafe); // n vaut 0
Notez que quand la valeur retourne de executeUpdate est 0, cela peut vouloir dire deux choses :
- soit l'instruction excute est une mise jour et que 0 ligne est affect.
- soit l'instruction est une instruction DDL.
Le code suivant insre les lignes pour les trois fournisseurs dans FOURNISSEURS :
stmt.executeUpdate("insert into FOURNISSEURS values (101,'Acme, Inc.',"
+ " '99 Market Street', 'Groundsville', 'CA', '95199')");
stmt.executeUpdate("insert into FOURNISSEURS values (49,'Superior Coffee',"
+ " '1 Party Place', 'Mendocino', 'CA','95460')");
stmt.executeUpdate("insert into FOURNISSEURS values (150,'The High Ground',"
+ " '100 Coffee Lane', 'Meadows', 'CA','93966')");
Exercice 4
Ecrivez un programme JAVA crant la table FOURNISSEURS et ajoutant les trois fournisseurs.
Maintenant que nous avons les tables CAFES et FOURNISSEURS, nous pouvons procder au scnario ou
le propritaire de "The Coffee Break" veut obtenir la liste des cafs qu'il a achets auprs d'un fournisseur
en particulier.
12
Exercice 5
Ecrivez un programme donnant la liste des cafs achets auprs d'un fournisseur dont le nom est donn en
paramtre du programme.
Exemple de rsultat produire :
Le(s) caf(s) achet(s) Acme, Inc. :
Colombian
Colombian_Decaf
A prsent, vous connaissez les bases de JDBC. Les deux sections qui suivent correspondent des notions
avances : les transactions et les procdures stockes.
9) Transactions
Parfois, vous ne voulez pas qu'une instruction prenne effet sans qu'une autre lui succde. Par exemple,
quand le propritaire du "The Coffee Break" met jour le montant de caf vendu chaque semaine, il
aimerait aussi mettre jour le montant total des ventes jusqu' maintenant. Donc, il ne veut pas mettre
jour l'un sans mettre jour l'autre, sinon les donnes ne seraient pas cohrentes. La manire pour tre sr
que toutes les actions et interactions voulues s'effectuent est d'utiliser une transaction. Une transaction est
un jeu d'une ou plusieurs instructions qui sont excutes ensembles de faon unitaire, donc toutes les
instructions sont excutes, ou aucune.
9.1 Dsactiver le mode Auto-commit
Quand une connexion est cre, elle est en mode auto-commit. Ce qui veut dire que chaque instruction
SQL est traite comme une transaction et prendra automatiquement effet aprs sa bonne excution. (Pour
tre plus prcis, une instruction SQL prend automatiquement effet sur la base de donnes lorsqu'elle est
termine, et non pas quand elle est excute). Une instruction est termine quand tous ses rsultats et toutes
ses mises jour ont t rapports. La manire d'autoriser deux ou plusieurs instructions tre groupes
dans une transaction est de mettre hors service le mode auto-commit. Si conn est notre connexion active,
nous avons alors :
conn.setAutoCommit(false);
13
conn.commit();
conn.setAutoCommit(true);
Quand la mthode commit est appele (automatiquement quand auto-commit est active ou explicitement
quand il est dsactiv), tous les changements rsultants des instructions de la transaction seront permanents.
Dans ce cas, cela signifie que les colonnes VENTES et TOTAL pour le caf Colombian ont t modifies
50 (si TOTAL tait 0) et retiendra cette valeur jusqu' ce qu'elle soit modifie par une instruction.
La dernire ligne de l'exemple prcdent active le mode auto-commit, ce qui veut dire que chaque
instruction prend ds lors effet automatiquement sur la base de donnes quand elle est termine. Vous
revenez donc l'tat par dfaut, celui o vous n'avez plus appeler la mthode commit. Il est conseill de
dsactiver le mode auto-commit uniquement quand vous tes en mode transaction. De cette faon, vous
rduisez les chances de conflit au niveau des entres dans la base de donnes avec les autres utilisateurs.
Exercice 6 (facultatif)
Ecrivez un programme JAVA correspondant l'exemple prcdent.
Le code qui suit met l'instruction SQL dans une chane de caractres et l'assigne la variable
createProcedure, que nous utiliserons plus tard :
String createProcedure = " CREATE PROCEDURE SHOW_FOURNISSEURS ()"
+ " AS BEGIN"
+ " SELECT FOURNISSEURS.NOM_FO, CAFES.NOM_CAFE"
+ " FROM FOURNISSEURS, CAFES"
+ " WHERE FOURNISSEURS.FO_ID = CAFES.FO_ID"
+ " ORDER BY NOM_FO"
+ " END";
15
Le fragment de code suivant utilise l'objet Connexion conn pour crer un objet Statement, qui sera
utilis pour envoyer l'instruction SQL afin de crer la procdure stocke sur la base de donnes :
Statement stmt = conn.createStatement();
stmt.executeUpdate(createProcedure);
La procdure SHOW_FOURNISSEURS sera compile et stocke dans la base de donnes comme un objet
pouvant tre appel de faon similaire l'appel d'une mthode.
10.2 Appeler une procdure stocke avec JDBC
JDBC vous permet d'appeler une procdure stocke sur la base de donnes depuis une application crite en
JAVA. La premire tape est de crer un objet CallableStatement. Comme avec les objets
Statement et PreparedStatement, ceci est fait avec une connexion ouverte. Un objet
CallableStatement contient l'appel d'une procdure, il ne contient pas la procdure elle-mme. La
premire ligne de code ci-dessous cre un appel la procdure stocke SHOW_FOURNISSEURS en
utilisant la connexion conn. La partie qui est entre accolade est la syntaxe pour la procdure stocke.
Quand le driver rencontre "{call SHOW_FOURNISSEURS}", il traduira cette syntaxe en SQL natif utilis
par la base de donnes pour appeler la procdure stocke nomme SHOW_FOURNISSEURS :
CallableStatement cs = conn.prepareCall("{call SHOW_FOURNISSEURS}");
ResultSet rs = cs.executeQuery();
Notez que la mthode pour excuter cs est executeQuery car cs appelle une procdure stocke qui
contient une requte et produit un resultset. Si la procdure avait contenue une mise jour ou une des
instructions DDL, la mthode executeUpdate aurait t utilise. Comme c'est parfois le cas, une
procdure stocke contient plus d'une instruction SQL, qui pourrait produire plus d'un resultset, plus d'une
mise jour, ou une combinaison de resultsets et de mise jour. Dans ce cas, lorsqu'il y a de multiples
rsultats, la mthode execute devra tre utilise pour excuter CallableStatement.
La classe CallableStatement est une classe drive de PrepareStatement, donc un objet
CallableStatement peut avoir des paramtres d'entres tout comme l'objet PreparedStatement. En
plus, un objet CallableStatement peut avoir des paramtres de sorties ou des paramtres qui sont fait
pour l'entre et la sortie. Les paramtres INOUT et la mthode execute sont rarement utiliss.
16
ANNEXE
Exemple de programme utilisant JDBC :
(disponible ici : http://nicolas.durand.perso.luminy.univmed.fr/pub/bd/tpjdbc/Test.java)
import java.sql.*;
public class Test {
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
int i = -1;
String s = null;
float f = -1;
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
}
catch (ClassNotFoundException e) {
System.err.println("Erreur lors du chargement du pilote : " + e.getMessage());
e.printStackTrace();
}
try {
conn =
DriverManager.getConnection("jdbc:oracle:thin:@pedaserv1.luminy.univmed.fr:1521",
"compteN","compteN");
stmt = conn.createStatement();
rs = stmt.executeQuery("SELECT a, b, c FROM Table");
while(rs.next()) {
i = rs.getInt("a");
s = rs.getString("b");
f = rs.getFloat("c");
System.out.println(i+"\t"+s+"\t"+f);
}
}
catch(SQLException e2) {
System.err.println("Erreur : " + e2.getMessage());
e2.printStackTrace();
}
finally {
try {
if(rs != null) rs.close();
if(stmt != null) stmt.close();
if(conn != null) conn.close();
}
catch(SQLException e3) {
System.err.println("Erreur lors de la fermeture des ressources : "
+ e3.getMessage());
e3.printStackTrace();
}
}
}
}