JAVA|
DATABASE|
Connectivity|
Plan
q Bases de données, interface JDBC
Introduction, concepts
q Pilote et gestionnaire de pilotes
Interface java.sql.Driver
Le cas ODBC
q Accès aux données
Charger un pilote
Créer une connexion à la base
Créer une requête (Statement)
Exécuter une requête
Présenter les résultats
q Accès aux métadonnées
q Traiter les erreurs
JDBC
Objectif du Java DataBase Connectivity :
- Accéder aux SGBD à l'aide de requêtes SQL
- Récupérer les résultats en Java
- Le type de la base est transparent (Sybase,
Oracle, MySql, Access ...)
JDBC
JDBC : Java DataBase Connectivity
Objectif :
- Accéder aux SGBD à l'aide de requêtes SQL
- Récupérer les résultats en Java
- Le type de la base est transparent (Sybase,
Oracle, MySql, Access ...)
- généricité, standardisation
généricité, standardisation
Ø JDBC définit un ensemble d'interfaces Java: Driver,
Connection, Statement, ResultSet, ... ainsi qu’ une classe
DriverManager.
Ø Chaque base de données particulière possède sa propre
implémentation des interfaces : c'est la notion de pilote ou
driver.
JDBC Vs. ODBC
JDBC Vs. ODBC
Étape pour JDBC
ØImporter les packages nécessaires.
ØEnregistrer les drivers JDBC.
ØEtablir une connexion.
ØCréer des JDBC Statement/preparedStatement.
ØExécuter les requêtes crées auparavant.
ØRécupérer les ‘ResultSet’.
ØFermer les objets resultset & statement.
ØFermer la connexion.
Étape pour JDBC
ØImporter les packages nécessaires.
import java.sql.*; // JDBC package
import java.math.*;
import java.io.*;
…
Étape pour JDBC
ØCharger le pilote JDBC.
class testConnection{
public static void main (String args []){
try{
// Appel du driver jdbc pour le SGBD ciblé
Class.forName(“sun.jdbc.odbc.JdbcOdbcDriver”);
Class.forName(“oracle.jdbc.driver.OracleDriver”);
Class.forName(“org.postgresql.Driver”);
…
} catch(ClassNotFoundException e){
System.out.println("Error loading driver"); }
}
Étape pour JDBC
ØÉtablir la connexion.
String user = “…”;
String password = “…” ;
String url_ODBC = “jdbc:odbc:NomBD”;
String url_MySQL = “jdbc:mysql://localhost:3306/userbd”;
String url_PostGreSQL = “jdbc:postgres://localhost:5432/bd1”;
// Connection à la base de donnée spécifiée dans l’url
Connection conn =
DriverManager.getConnection(url, user, password);
…
Étape pour JDBC
ØÉtablir la connexion.
// on peut aussi directement inclure les propriétés de connexion
// dans l’url dans à les définir séparément
String url1 =
“jdbc:postgres://localhost:5432/bd1?user=…&password=…”;
// Connection à la base de donnée spécifiée dans l’url
Connection conn = DriverManager.getConnection(url);
ØDifférentes propriétés peuvent être définies dans l’url:
ssl = boolean; loginTimeout = int; connectTimeout = int;
preparedStatementCacheSizeMiB = int; …
Étape pour JDBC
ØÉtablir la connexion.
// plusieurs adresses d’hôtes peuvent être définies dans l’url
// afin de chercher la base de données cible sur plusieurs
// serveurs successivement
String url1 = “jdbc:postgresql://host1:port1,host2:port2/db?... ”;
// Connection à la base de donnée spécifiée dans l’url
Connection conn = DriverManager.getConnection(url);
Étape pour JDBC
ØCréer des Statement.
Statement pstmt =
conn.createStatement ("SELECT * FROM employe");
Étape pour JDBC
ØCréer des preparedStatement.
PreparedStatement pstmt = conn.prepareStatement
("SELECT * FROM employe WHERE nom = ?");
pstmt.setString(1, “Ahmed");
Étape pour JDBC
ØExécuter des requêtes (sans retour):
preparedStatement pstmt = conn.prepareStatement
(" insert into employe values(?,?,?)");
pstmt.setInt(1,7839); pstmt.setString(2,E7839);
pstmt.setString(3,”KING”);
int i = pstmt.executeUpdate();
La valeur de la variable i peut pour une opération
d’insertion, prendre les valeurs 1 (ajout d’une ligne), ou 0
en cas d’exception.
Étape pour JDBC
ØExécuter des requêtes (avec retour).
PreparedStatement pstmt = conn.prepareStatement
("SELECT * FROM employe WHERE emp_id > ?");
pstmt.setInt(1,7333);
ResultSet rset = pstmt.executeQuery ();
rset
Étape pour JDBC
ØParcourir le ResultSet (dans le cas de sélection).
PreparedStatement pstmt = conn.prepareStatement
("SELECT * FROM employe WHERE emp_id > ?");
pstmt.setInt(1,7333);
ResultSet rset = pstmt.executeQuery ();
// Afficher le contenu de la réponse
while (rset.next ())
System.out.println (rset.getInt(1)+" "+ rset.getString(3));
rset
1 2 3
Étape pour JDBC
ØFermer la connexion.
PreparedStatement pstmt = conn.prepareStatement
("SELECT * FROM employe WHERE nom = ?");
pstmt.setString(1, “Ahmed");
ResultSet rset = pstmt.executeQuery ();
// Afficher le contenu de la réponse
while (rset.next ())
System.out.println (rset.getString (1)+" "+ rset.getString(2));
…
// fermer le ResultSet, Statement, ainsi que la connection
rset.close(); pstmt.close(); conn.close();
…
Étape pour JDBC
ØRequêtes sans retour
PreparedStatement requete=con.prepareStatement
("INSERT INTO employe(Num,Nom) VALUES (?,?)");
requete.setInt(1,305);
requete.setString(2, "Ahmed");
int result=requete.executeUpdate();
System.out.println(result+" Enregistrement ajouté");
// fermer le Statement, ainsi que la connection
pstmt.close(); conn.close();
…
Statement vs. preparedStatement
ØLors de l’utilisation d’une requête sans paramètres
(requête statique), on peut utiliser l’objet Statement.
Statement req = conn.createStatement ();
ResultSet rset = req.executeQuery ("SELECT * FROM employe");
// Afficher le contenu de la réponse
while (rset.next ())
System.out.println (rset.getString (1)+" "+ rset.getString(2));
…
Statement vs. preparedStatement
ØLors de l’utilisation d’une requête sans paramètres
(requête statique), on peut utiliser l’objet Statement.
Statement req = conn.createStatement ();
ResultSet rset = req.executeQuery ("SELECT * FROM employe");
// Afficher le contenu de la réponse
while (rset.next ())
System.out.println (rset.getString (1)+" "+ rset.getString(2));
…
ØPour les requêtes paramétrées, ou dans le cas d’une
requête redondante avec des valeurs différentes, l’objet
preparedStatement est plus approprié.
JDBC types
Types JDBC Types JAVA
Fonctions JDBC
{
Types
{ Fonctions
SQL JDBC
Types du ResultSet
ØLes types des ResultSet (dans le cas de sélection):
Lors de l’appel des méthodes createStatement() ou
prepareStatement(), il est possible de définir les deux paramètres
resultSetType et resultSetConcurrency
Types du ResultSet
ØLes types des ResultSet (dans le cas de sélection):
Lors de l’appel des méthodes createStatement() ou
prepareStatement(), il est possible de définir les deux paramètres
resultSetType et resultSetConcurrency {
{
ResultSet.CONCUR_READ_ONLY
ResultSet.TYPE_FORWARD_ONLY
ResultSet.CONCUR_UPDATABLE
ResultSet.TYPE_SCROLL_INSENSITIVE
ResultSet.TYPE_SCROLL_SENSITIVE
Types du ResultSet
Les valeurs que peut prendre la propriété resultSetType :
ResultSet.TYPE_FORWARD_ONLY : c'est la valeur par défaut. Elle
indique que les déplacements du curseur se font en avançant de la
première à la dernière ligne (la méthode last renvoyant true), ainsi, le
ResultSet est fermé et les données ne sont plus accessibles.
ResultSet.TYPE_SCROLL_INSENSITIVE : le curseur peut être déplacé
dans les deux sens, ou positionné directement sur une ligne. Le
ResultSet est insensible aux modifications des valeurs dans la BD.
ResultSet.TYPE_SCROLL_SENSITIVE : le ResultSet est sensible aux
modifications des valeurs dans la BD, donc présente une vue dynamique
des données contenues dans le ResultSet.
Types du ResultSet
Les valeurs que peut prendre la propriété resultSetConcurrency :
ResultSet.CONCUR_READ_ONLY : c'est la valeur par défaut, dans
laquelle les données contenues dans le ResultSet ne peuvent qu'être
lues.
ResultSet.CONCUR_UPDATABLE : cette valeur indique que l'on peut
modifier les données de la base directement via le ResultSet.
Fonctions du ResultSet
next() : déplace le curseur sur la ligne suivante. Elle retourne true si le
curseur est positionné sur une ligne, false s’il dépasse la fin.
previous() : déplace le curseur sur la ligne précédente. Retourne true ou
false, suivant la position du curseur dans (hors) le tableau.
first(), last() : le curseur sur la première/dernière ligne du tableau.
beforeFirst(), afterLast() : positionne le curseur sur l'une des positions
virtuelles, avant/après la première/dernière ligne.
relative(int rows) : déplace le curseur d’un nombre de lignes indiqué,
vers le bas/haut du tableau si ce nombre est positif/négatif. Elle retourne
true si le curseur a été positionné sur une ligne valide, false dans le cas
contraire.
absolute(int rows) : positionne le curseur en absolu dans le tableau.
absolute(-1) positionne le curseur sur la dernière ligne.
Scrollable ResultSet
ØManipuler le ResultSet devient possible dans les
deux sens, par des positions absolues ou relatives.
Statement stmt =
con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet rs = stmt.executeQuery(“ select * from employes ”);
rs.next(); // se positionner sur l’element suivant
rs.relative(-5); // revenir en arrière de 5 enregistrements
rs.relative(7); // avancer de 7 enregistrements en avant
rs.absolute(100); // se positionner sur la 100éme ligne
rs.last(); // se positionner sur la dernière ligne
Updatable ResultSet
ØLe ResultSet permet d’avoir une perspective du contenu
de la BD, ainsi que la possibilité de le modifier directement.
Statement stmt =
con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
ResultSet rs = stmt.executeQuery(“ select * from employes ”);
while ( rs.next() ){
int grade = rs.getInt(“grade”);
rs.updateInt(“grade”, grade+10);
rs.updateRow();
}
Updatable ResultSet
ØUne autre possibilité consiste à ajouter une nouvelle ligne
dans la table de la BD. Avant de l’exécuter, il faudrait créer
une nouvelle ligne pour l’insertion (moveToInsertRow()) et de
mettre à jour cette nouvelle ligne (ResultSet.UpdateXXX()).
ResultSet rs = stmt.executeQuery(“ select * from employes ”);
rs.moveToInsertRow();
rs.updateInt(1, 7965); rs.updateString(2, “E7965”);
rs.updateString(“EMP_NAME”, “John”);
rs.insertRow(); // valider les modifications et les envoyer vers la BD
rs.moveToCurrentRow(); // repositionner le curseur du ResultSet
1 2 3
7965 E7965 John
Accès aux métadonnées
ØToutes les métadonnées sur la base sont accessibles au travers d'une
instance de DatabaseMetaData.
ØCet objet est accessible à travers la méthode getMetaData(),
appliquée sur l’objet Connection.
ØLes méthodes disponibles pour récupérer les différentes métadonnées
de la base de données sont :
o String getDriverName()
o String getDriverVersion()
o String getUserName()
o String getDatabaseProductName()
o String getDatabaseProductVersion()
o ResultSet getTables(String catalog, String schemaPattern,
String tableNamePattern, String[] types)
Accès aux métadonnées
ØChaque ResultSet possède ses propres Métadonnées, récupérable à
travers la fonction getMetaData(), qui renvoie des ResultSetMetaData.
ØUtilisées pour obtenir les noms/types des colonnes dans un ResultSet.
ØOn peut avoir accès à :
o Le nombre de colonne : getColumnCount()
o Le nom d'une colonne : getColumnName(int col)
o Le type d'une colonne : getColumnType(int col)
o ...