You are on page 1of 45

UNIVERSIT HASSAN 1ER

COLE NATIONALE DES SCIENCES


APPLIQUES KHOURIBGA

Connexion une Base de donnes en Java


Java DataBase Connectivity (JDBC)
Said EL KAFHALI
kafhalisaid@gmail.com

A.U: 2013/ 2014

Prsentation

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 les paquetages (packages) : java.sql et javax.sql
LAPI JDBC est presque totalement indpendante des SGBD (quelques
mthodes ne peuvent tre utilises quavec certains SGBD mais ne doivent
tre utilises quen cas de ncessit imprieuse pour amliorer les
performances)
http://java.sun.com/products/jdbc/overview.html
http://java.sun.com/docs/books/tutorial/jdbc/
JDBC : interaction avec un SGBD
Localement ou distance
Avec une base de donne relationnelle

Prsentation

Fonctionne selon un principe client/serveur


Client = le programme Java
Serveur = la base de donnes
Principe
Le programme Java ouvre une connexion avec le SGBD
Il envoie des requtes SQL
Il rcupre les rsultats
Il met jour la BD (avec ou sans transaction)
Il ferme la connexion.

Mise en uvre dune application Java-JDBC

1.
2.
3.
4.
5.
6.
7.

Pour effectuer un traitement avec une base de donnes, il faut:


Charger un pilote en mmoire,
Dfinir lURL de connexion,
Etablir une connexion avec la base de donnes,
Rcuprer les informations relatives la connexion,
Excuter des requtes SQL et/ou des procdures stockes,
Traiter les donnes retournes
Fermer les diffrents espaces de travail

tape 1: charger le pilote

Pilote: contient toutes les classes ncessaire pour communiquer avec une base
de donnes.
Ce pilote est gnralement disponible dans un package jar. Le chemin doit
tre votre variable denvironnement CLASSPATH pour permettre au
programme de lutiliser.
Pour charger le pilote il faut utiliser la mthode forName de la classe
Class.
La mthode Class.forName(String driver)peut lever une exception de
type ClassNotFoundException si il y a une erreur lors du chargement du
driver.
Par exemple , si le nom de la classe est package.DriverXXX, le chargement
du driver se fera avec le code suivant:

Class.forName("package.DriverXXX");
Pour une base Oracle: oracle.jdbc.driver.OracleDriver
Pour une base Access: sun.jdbc.odbc.JdbcOdbcDriver
Pour une base PostgreSQL : postgresql.driver
Pour une base MySQL : org.gjt.mm.mysql.Driver

Plus dinformations sur les pilotes jdbc: http://java.sun.com/jdbc/drivers.html

Exemples

Le chargement du pilote pour une base de donnes Access :


try{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
} catch (ClassNotFoundException e){

Le chargement du pilote pour une base de donnes MySQL:


try{
Class.forName("org.gjt.mm.mysql.Driver");
} catch (ClassNotFoundException e){

tape 2: Dfinir lURL de connexion

Par exemple, comment paramtrer une source de donnes ODBC:


Dans le Panneau de configuration, systme et scurit, outils
dadministrations, ouvrir sources de donnes ODBC
Activer longlet Sources de donnes systme/utilisateur
Cliquer sur le bouton Ajouter pour ajouter une DNS

tape 2: Dfinir lURL de connexion (suite)

Slectionner le pilote ODBC Microsoft Access Driver (*.mdb,*.accdb) ,


puis cliquer sur le bouton Terminer

tape 2: Dfinir lURL de connexion (suite)

Indiquer un nom pour la source de donnes, une description,


Cliquer sur le bouton Slectionner pour dfinir la localisation de la base,
puis sur Ok, et fermer la fentre de ladministration de source ODBC.

Le nom de la base de donnes tant celle dclare dans le panneau de


configuration ODBC, cest--dire le nom du DNS.
La syntaxe de lURL est gnralement de la forme suivante:

String url ="jdbc:sousprotocole:SourceDeDonnes";


9

Exemples

Grce au pont JDBC-ODBC:


String url ="jdbc:odbc:SourceDeDonnes";

Grce un driver spcifique MySQL:


String url ="jdbc:mysql://server/SourceDeDonnes";

Grce des drivers spcifiques Oracle:


String url ="jdbc:oracle:oci8:@SourceDeDonnes";
// SourceDeDonnes tant le SERVICE_NAME

String url ="jdbc:oracle:thin:@server:1521:SourceDeDonnes";

10

tape 3: Crer une connexion

La connexion une base de donnes se fait par le biais de linstanciation


dun objet de linterface Connection.
Linterface Connection utilise les mthodes getConnection() de la classe
DriverManager pour tablir la connexion avec la base de donnes. Pour
cela on passe lurl de la base de donnes en paramtre la mthode.
Les mthodes getConnection() peuvent lever une exception de la classe
java.sql.SQLException.
La cration dune connexion simple se fait grce la mthode suivante:

public static Connection getConnection (String url) throws


SQLException;

Utilisation :
try{
Connection conn =DriverManager.getConnection(url);
} catch (SQLException e){
.
}

11

tape 3: Crer une connexion (suite)

La cration dune connexion avec un nom dutilisateur et un mot de passe se


fait grce la fonction:

public static Connection getConnection(String url, String


login, String password)throws SQLException;

Utilisation :
String login="Toto";
String password= " ********* ";
try{ Connection conn =DriverManager.getConnection(url,
"login", " password");
} catch (SQLException e){
.}

Linterface Connection dispose de plus de mthodes permettant de fermer


la connexion ainsi que de tester son tat:
public void close() throws SQLException; // conn.close();
public boolean isClosed() throws SQLException;
12

tape 4: Traitement des requtes SQL

Pour traiter une requte SQL, on dispose de plusieurs objets capables


denvoyer celle-ci la base de donnes:
Statement: objet utilis pour lexcution dune requte SQL statique
retournant les rsultats quelle produit.
PreparedStatement : objet utilis lorsquil est ncessaire dexcuter une
requte plusieurs fois, avec des paramtres diffrents.
CallableStatement : objet utilis pour appeler une procdure stocke.
Des instances de ces objets sont disponibles grce linstance de linterface
Connection.

13

Linterface Statement

Lobjet Statement reprsente une instruction de traitement SQL. Il est cr


par lintermdiaire dune instance de Cennection par la mthode:
public Statement createStatement() throws SQLException;

Exemple:
try{
Statement state =conn.createStatement();
} catch (SQLException e){
.}

14

Linterface Statement (suite)

Cet objet est pourvu de mthodes permettant de faire excuter:


Une requte SQL de consultation (SELECT), retournant les rsultats de
celle-ci:
public ResultSet executeQuery(String sql)throws
SQLException;

Une requte de modification (UPDATE, DELETE, INSERT, CREATE,


DROP), ne renvoyant que le nombre doccurrences affectes par celle-ci:
public int executeUpdate(String sql) throws
SQLException;

Un lot de requtes, renvoyant un tableau dentiers correspondant au


rsultat de la requte:

public int[] executeBatch() throws SQLException;


// Utilis conjointement avec les mthodes
public void addBatch(String sql) throws SQLException;
public void clearBatch() throws SQLException;
15

Exemples

Obtenir les noms des lves de la table Etudiant, classs par ordre alphabtique:

try{
ResultSet resultat =state.executeQuery("SELECT DISTINCT Nom
FROM Etudiant ORDER BY Nom; ");
} catch (SQLException e){
.}

Crer une table Enseignant dans la table de base de donnes courante:

try{
state.executeUpdate("CREATE TABLE Enseignant " +
"( Enseignant_ID integer " + ", Departement_ID integer " + ",
Nom char(25) " +", Prenom char(25) " + ", Grade char(25) " +
", Salaire numeric(6,0) " + ") "; ");
} catch (SQLException e){
.}
16

Exemples (suite)

Supprimer loccurrence denseignant ayant lidentifiant 23416 et de fixer tous


les salaires 20000 minimum:

try{
state.addBatch("DELETE FROM Enseignant WHERE Enseignant_ID
=23416");
state.addBatch("UPDATE Enseignant SET Salaire = 20000 WHERE
Salaire<20000");
int [] results=state.executeBatch();
} catch (SQLException e){
.}

17

Linterface PreparedStatement

Lobjet PreparedStatement reprsente une instruction de traitement SQL


prcompile. Cest une sous-interface de Statement.
Cet objet est gnralement utilis pour remplacer les requtes classiques, en
tant plus srs et plus efficaces. Un PreparedStatement typique ressemble
ceci : SELECT * FROM Pays WHERE code = ?
Lorsque la requte ci-dessus est excute, vous devez spcifier la valeur qui
vient remplacer le ? dans cette requte.
Il est cr par lintermdiaire dune instance de Connection par la mthode:

public PreparedStatement preparedStatement(String sql)


throws SQLException;

Utilisation:
try{
PreparedStatement prepState=conn.preparedStatement(sql);
} catch (SQLException e){
.}
18

Linterface PreparedStatement (suite)

Cet objet est pourvu de mthodes permettant de:


Excuter la requte SQL, retournant les rsultats de celle-ci:
public ResultSet executeQuery() throws SQLException;
public int executeUpdate() throws SQLException;

Spcifier le type de la valeur de tel ou tel argument:

public void setXxxx(int indiceParameter, Xxxx value)


throws SQLException;
// o Xxxx est le type de la valeur
setString(int indiceParameter, String value);
setInt(int indiceParameter, int value);

Vider la liste des paramtres :

public void clearParameters() throws SQLException;

19

Exemple
try{

PreparedStatement prepState=conn.preparedStatement("
SELECT Nom FROM Enseignant WHERE Salaire=? and
Departement_ID=? ");
prepState.setString(1,"Mohamed");
prepState.setInt(2, 25000);
ResultSet rs=prepState.executeQuery();

prepState.clearParameters();
prepState.setString(1,"Mourad");
prepState.setInt(2, 27000);
rs=prepState.executeQuery();

} catch(SQLExecption e){

}
20

Linterface CallableStatement

La plupart des SGBD incluent un langage de programmation interne (ex:


PL/SQL dOracle) permettant aux dveloppeurs dinclure du code
procdural dans la BD, code pouvant tre ensuite invoqu depuis dautres
applications.
le code est crit une seule fois est peut tre utilis par diffrentes
applications.
permet de sparer le code des applications de la structure interne des
tables. (cas idal : en cas de modification de la structure des tables seul
les procdures stockes ont besoin dtre modifies)
Utilisation des procdure stockes depuis JDBC indpendante de la manire
dont celles-ci sont gres par le SGBD
Utilisation possible de la valeur de retour
Gestion des paramtres IN, OUT, INOUT

21

Linterface CallableStatement (suite)

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.

public CallableStatement prepareCall(String sql) throws


SQLException;

Utilisation:
try{
CallableStatement prepState=conn.prepareCall(sql);
} catch (SQLException e){
.}

Les syntaxes pour lappel de procdures stockes sont:


{call procedure _name[(?, ?, ...)]}
{?=call procedure_name [(?, ?, ...)]}
22

Linterface CallableStatement (suite)

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.
public void registerOutParameter(int numParam, int
typeSQL) throws SQLException;
// o numParam est le rang du paramtre
// o typeSQL est le type SQL du paramtre (constante
disponible dans java.sql.Types) (voir plus loin dans
ce cours).

23

Exemple
CallableStatement cs =conn.prepareCall(" {call
SHOW_FOURNISSEURS} ");
ResultSet rs =cs.executeQuery();

La premire ligne de code ci-dessus cre un appel la procdure


SHOW_FOURNISSEURS en utilisant la connexion conn.
Quand le driver rencontre " {call SHOW_FOURNISSEURS} ", il traduira
cette syntaxe en SQL natif utilis par la base de donnes.
La syntaxe de procdure stocke peut prendre plusieurs formes :
{call nom_procedure_stockees}: cette forme la plus simple permet
l'appel d'une procdure stocke sans paramtre ni valeur de retour
{call nom_procedure_stockees(?, ?, ...)}: cette forme permet
l'appel d'une procdure stocke avec des paramtres
{? = call nom_procedure_stockees(?, ?, ...)}: cette forme
permet l'appel d'une procdure stocke avec des paramtres et une valeur
de retour
24

tape 5:Traiter les donnes retournes

Lors dune requte SQL de consultation (SELECT), un objet ResultSet est


retourn. Celui-ci reprsente la liste des donnes retournes par la requte.
Un objet de type ResultSet reprsente une table, cest dire un ensemble de
lignes et de colonnes. A un moment donn, on na accs qu une ligne de la
table appele ligne courante.
ResultSet fournit une mthode permettant de rcuprer une instance de
ResultSetMetaData, qui comprend toutes les proprits de la structure
(nom de colonne, type, accs):
public ResultSetMetaData getMetaData();

25

Lecture des donnes de ResultSet

La table du ResultSet a des colonnes col1, col2,.... Pour exploiter les diffrents
champs de la ligne courante, on dispose des mthodes suivantes :
boolean next(): positionner le curseur sur lenregistrement suivant et rend
true si elle russit, false sinon.
public Xxxx getXxxx(int indiceCol): accder la valeur du type
donn et la colonne donne par indice de lenregistrement actuellement point par
le curseur.
public Xxxx getXxxx(String nomCol): accder la valeur du type
donn et la colonne donne par nom de lenregistrement actuellement point par le
curseur.

o Xxxx est le type de la valeur


getString(int indiceCol);
getInt(int indiceCol);

26

Exemple

Cet exemple permet dafficher la liste des enseignants, suivi de leur


identifiant et de leur salaire.

ResultSet rs =state.executeQuery("SELECT *FROM


Enseignant");
While(rs.next){
System.out.println(" [" +
rs.getString("Nom")+
" , "+
rs.getInt("Enseignant_ID")+
" , "+
rs.getInt("Salaire")+
" ] ");
}

27

Modification des donnes de ResultSet

public void updateXxxx(int indiceCol, Xxxx


la valeur de type donn et la colonne donne par indice
actuellement point par le curseur.
public void updateXxxx(String nomCol, Xxxx
la valeur de type donn et la colonne donne par nom
actuellement point par le curseur.

value):Modifier
de lenregistrement
value): Modifier
de lenregistrement

o Xxxx est le type de la valeur


updateString(int indiceCol, String value);
updateInt(int indiceCol, int value);

public void updateRow():Appliquer dans la base de donnes les


changements effectus sur lenregistrement actuellement point par le curseur.
public void insertRow():insrer dans la base de donnes lenregistrement
actuellement point par le curseur.
public void moveToinsertRow():aller sur un emplacement vide
permettant dinsrer un nouvel enregistrement.
28

Exemple

Cet exemple permet de un enregistrement, puis den insrer un nouveau et


daffecter les changements dans la base pour chacun deux.

ResultSet rs =state.executeQuery("SELECT *FROM


Enseignant");
rs.next();
rs.updateString("Nom","Mohamed");
rs.updateInt("Enseignant_ID ",2543);
rs.updateInt("Salaire",25000);
updateRow();
rs.moveToInsertRow();
rs.updateString("Nom","Mourad");
rs.updateInt("Enseignant_ID ",2543);
rs.updateInt("Salaire",25000);
rs.insertRow();
29

ResultSet JDBC 2.0 (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 prcdente
beforeFirst(): Positionne avant la premire ligne
afterLast(): Positionne aprs la dernire ligne
absolute(int): Positionne une ligne donne
relative(int): Dplacement dun nombre de lignes donn par rapport
ligne courante

30

ResultSet JDBC 2.0 (Mthodes de test)

boolean isFirst(): True si curseur positionn sur la premire ligne


boolean isBeforeFirst(): True si curseur positionn avant la
premire ligne
boolean isLast(): True si curseur positionn sur la dernire ligne
boolean isAfterLast(): True si curseur positionn aprs la
dernire ligne

31

tape 5 : Gestion des transactions

L interface Connection offre des services de gestion des transactions

public void setAutoCommit(boolean autoCommit) throws


SQLException: activer/ dsactiver la validation automatique de chaque

requte passe (auto-commit par dfaut).

public

void

commit()throws

SQLException:

dclenche

validation de la transaction

public void rollback() throws SQLException: annule la

transaction

32

Exemple
try {
con.setAutoCommit(false);
Statement stmt=conn.createStatement();
stmt.executeUpdate("UPDATE Enseignant SET Salaire = 23000
WHERE Enseignant_ID = 5");
stmt.executeUpdate("DELETE FROM Enseignant WHERE
Salaire<20000");
con.commit()}
catch (SQLException e) {
try{
conn.rollback();
}
catch (SQLException e) {
}
}
33

Correspondance type SQL-type Java

34

tape 6 : fermer les diffrents espaces de travail

Cette tape est effectue par lappel de la fonction close() des objets
Statement, PreparedStatement, CallableStatement, Connection et
ResultSet.
Linstance dun Statement doit tre ferme avant de relancer une requte
SQL.
Exemple:
try{
rs.close();
state.close();
conn.close();
} catch( SQLException e){

35

Objet DatabaseMetaData

Les objets de la classe DatabaseMetaData donnent des informations au sujet du


SGBD et du catalogue de la base de donnes grce la mthode de linterface
Connection.
public DatabaseMetaData getMetaData() throws SQLException;

Exemple:
try{
DatabaseMetaData dbMetaData=conn.getMetaData();
System.out.println(" Base : "
+dbMetaData.getDataBaseProductName());
System.out.println(" Nom du pilote : "
+dbMetaData.getDriverName());
System.out.println(" Utilisateur : "
+dbMetaData.getUserName());

} catch (SQLException e){


}
36

Objet DatabaseMetaData (suite)

Un objet de la classe DatabaseMetaData contient 134 mthodes!!!


getCatalogs() throws SQLException : retourne lensemble des
bases de donnes du serveur
getTables(String dbName, String arg1, String arg2,
String[] arg3) : retourne la liste des tables de la base de donnes

indique en argument.
- getColumns(String dbName,
String arg1, String table,
String arg3): retourne lensemble des colonne de la table spcifie.
- getIndexInfo()
- getMaxConnections()
etc.

37

La classe ResultSetMetadata

La classe ResultSetMetaData nous donne des informations sur la structure


de la table lie une requte SQL, cest dire sur la nature de ses colonnes.
On a accs aux informations sur la structure dun ResultSet en instanciant
tout dabord un objet ResultSetMetaData. Si RS est un ResultSet, le
ResultSetMetaData associ est obtenu par : RS.getMetaData()

On notera les mthodes utiles dans la classe ResultSetMetaData :


1. int getColumnCount(): retourne le nombre de colonnes du
ResultSet
2. String getColumnName(int i): retourne le nom de la colonne i
du ResultSet (i>=1).
3. int getColumnType(int i): retourne le type de la colonne i du
ResultSet
4. String getColumnDisplaySize(int i): retourne la taille de
la colonne i du ResultSet (i>=1).
38

Exemple
Statement state =conn.createStatement();
ResultSet rs=state.executeQuery(" SELECT * FROM
Enseignant");
ResultSetMetaData rsMeta=rs.getMetaData();
System.out.println(rsMeta.getColumnCount());
for(i=1;i<=rsMeta.getColumnCount();i++){
System.out.println("colonne "+ i + " :"
+rsMeta.getColumnName(i)+", "
+rsMeta.getColumnType(i)+", "
+rsMeta.getColumnDisplaySize(i));
}

39

Les fonctionnalits de l'objet ResultSet

Il est possible de paramtre de type daccs que lon aura au niveau des
rsultats obtenus grce aux mthodes de linterface Connection:

Public Statement createStatement( int resultSetType, int


resulteSetConcurrency) throws SQLexception;
Public PreparedStatement prepareStatement( String sql, int
resultSetType, int resulteSetConcurrency) throws
SQLexception;
Public CallableStatement prepareCall( String sql, int
resultSetType, int resulteSetConcurrency) throws
SQLexception;

Les paramtres resultSetType et resultSetConcurrency tant des constantes


de linterface ResultSet utilises pour la rcupration des donnes renvoyes
par la base de donnes.
40

Les fonctionnalits de l'objet ResultSet (suite)

Le paramtre resultSetType correspondant au type de parcours du curseur


sur les rsultats:
TYPE_FORWARD_ONLY: parcours squentiel de chaque occurrence
TYPE_SCROLL_INSENSITIVE: les occurrences ne refltent pas les
mises jour qui peuvent intervenir durant le parcours
TYPE_SCROLL_SENSITIVE: scroll-sensitive : les occurrences refltent
les mises jour qui peuvent intervenir durant le parcours
Le paramtre resultSetConcurrency correspond la possibilit de mise
jour des donnes renvoyes par la base de donnes.
CONCUR_READ_ONLY : lecture seule
CONCUR_UPDATABLE : mise jour possible

41

Exemple
Statement statement =
conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet resultSet = statement.executeQuery("SELECT nom,
prenom FROM Enseignant");

42

Exemple de programme utilisant JDBC


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 {
catch (ClassNotFoundException e) {
Class.forName("oracle.jdbc.driver.OracleDriver");
System.err.println("Erreur lors du chargement du pilote :
" + e.getMessage());
e.printStackTrace();}
43

Exemple de programme utilisant JDBC (suite)


conn =
DriverManager.getConnection("jdbc:oracle:thin:@pedaserv1.l
uminy.univmed.fr:1521",
try {
"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);
}
}
44

Exemple de programme utilisant JDBC (suite)


catch(SQLException e2) {
System.err.println("Erreur : " + e2.getMessage());
e2.printStackTrace();
}
finally {
try {
if(rs != null) rs.close();
}
if(stmt != null) stmt.close();
catch(SQLException e3) {
if(conn != null) conn.close();
System.err.println("Erreur lors de la fermeture des
ressources : "
+ e3.getMessage());
e3.printStackTrace();}}}}
45