8. Java et les bases de données

publicité
8. Java et les bases de
données
Olivier Curé ­ UMLV [page 205 ]
ODBC
●
●
●
●
●
Open DataBase Connectivity.
Une API standard pour l'accès aux bases de
données.
En utilisant des instructions ODBC dans un
programme, on peut accéder à de nombreux
SGBD.
Permet au programme l'exploitation de SQL.
ODBC gère une requête SQL et transforme celleci dans un format compréhensible par le SGBD.
Olivier Curé ­ UMLV [page 206 ]
JDBC
●
●
Java DataBase Connectivity.
Une API Java pour connecter des programmes
java à des SGBD.
●
Un ensemble de classes et interfaces java.
●
JDBC va permettre
–
D'établir une connexion à la BD.
–
D'envoyer des requêtes SQL.
–
De récupérer les résultats des requêtes.
Olivier Curé ­ UMLV [page 207 ]
JDBC (2)
●
●
Il faut charger un driver pour le SGBD.
Il est possible d'utiliser l'interface JDBC
pour accéder aux BD accessibles via
ODBC => "pont" JDBC-ODBC.
Olivier Curé ­ UMLV [page 208 ]
JDBC (3)
●
Etapes :
–
Importer le package (import java.sql.*;).
–
Faire connaître le pilote JDBC du SGBD
–
Ouvrir une connexion à la BD.
–
Créer un objet 'Statement'.
–
Exécuter une requête et obtenir un objet
ResultSet.
–
Fermer les objets ResultSet et Statement.
–
Fermer la connexion à la BD.
Olivier Curé ­ UMLV [page 209 ]
Pilote JDBC
●
●
Le pilote JDBC est un composant logiciel qui
satisfait aux spécifications JDBC établies par Sun.
Ce pilote est spécifique à un fabriquant de base de
donnée. On trouvera par exemple un pilote pour les
bases de données Oracle, un pilote pour la base
MySQL. On traite dans ce cours du SGBDR MySQL.
Ce pilote est une classe Java qui implémente
l’interface java.sql.Driver. Pour le driver MySQL, cette
classe est : com.mysql.jdbc.Driver. Nous devons donc
charger cette classe. Pour cela, la méthode
Class.forName() est généralement utilisée (cf. Page
suivante).
Olivier Curé ­ UMLV [page 210 ]
Chargement du pilote
●
Il convient d'importer le package
java.sql
import java.sql.*;
public class QueryExample {
...
try {
Class.forName("com.mysql.jdbc.Driver");
}
catch (ClassNotFoundException e) {
System.err.println("Driver loading error : " + e);
}
...
}
Olivier Curé ­ UMLV [page 211 ]
URL de connection
●
●
●
Afin de localiser la base de donnée sur le serveur de
base de donnée, il est indispensable de spécifier une
adresse de connexion sous la forme d'une URL. Ces
URL commenceront toutes par "jdbc:".
Généralement, il faudra se référer à la
documentation du fournisseur du driver afin de
connaître le format de l'URL à utiliser.
Pour MySQL, l'URL est la suivante :
jdbc:mysql://host:port/database.
●
Host
: correspond à l'adresse IP du serveur.
●
port
: port MySQL ou port par défaut.
●
Database
: le nom de la base de donnée à laquelle on
doit se connecter.
Olivier Curé ­ UMLV [page 212 ]
Etablir une connexion
●
Etablir une connexion en utilisant la classe
java.sql.DriverManager. Son rôle est de
créer des connexions en utilisant le driver
préalablement chargé. Cette classe dispose
d'une méthode statique getConnection()
prenant en paramètre l'URL de connexion, le
nom d'utilisateur et le mot de passe.
String url = "jdbc:mysql://localhost/tp";
try {
Connection connection = DriverManager.getConnection(url, "root", "secret");
}
catch (SQLException e) {
System.err.println("Error opening SQL connection: " + e.getMessage()); }
Olivier Curé ­ UMLV [page 213 ]
Les requêtes
●
Afin d'exécuter des requêtes, il
convient d'utiliser un object Statement. Une
instance de cet objet est retourné par
un appel à la méthode
Connection.createStatement() :
try {
Statement statement = connection.createStatement();
}
catch (SQLException e) {
System.err.println("Error creating SQL statement: " + e.getMessage());
}
Olivier Curé ­ UMLV [page 214 ]
Les requêtes (2)
●
Il existe deux types de requêtes :
–
des requêtes de sélection (SELECT), accessibles
par la méthode Statement.executeQuery().
Cette méthode retourne un résultat de type
java.sql.ResultSet contenant les lignes
sélectionnées.
–
des requêtes de modification (UPDATE),
d'insertion (INSERT) ou de suppression (DELETE),
accessibles par la méthode
Statement.executeUpdate(). Cette méthode
retourne un résultat de type int correspondant
au nombre de lignes affectées par la requête.
Olivier Curé ­ UMLV [page 215 ]
Les requêtes (3)
String query = "SELECT name,email FROM users;";
try {
ResultSet resultSet = statement.executeQuery(query);
}
catch (SQLException e) {
System.err.println("Error executing query: " + e.getMessage());
}
String query = "UPDATE users SET email='[email protected]' WHERE name='JOHN SMITH';";
try {
int result = statement.executeUpdate(query);
}
catch (SQLException e) {
System.err.println("Error executing query: " + e.getMessage());
}
Olivier Curé ­ UMLV [page 216 ]
Traitement des résultats
●
L'objet ResultSet permet d'avoir un accès
aux données résultantes de notre requête en
mode ligne par ligne. La méthode
ResultSet.next() permet de passer d'une
ligne à la suivante. Cette méthode renvoie
false dans le cas où il n'y a pas de ligne
suivante. Il est nécessaire d'appeler au moins
une fois cette méthode, le curseur est placé
au départ avant la première ligne (si elle
existe).
Olivier Curé ­ UMLV [page 217 ]
Traitement des résultats
(2)
●
●
●
La classe ResultSet dispose aussi d'un certain
nombres d'accesseurs (ResultSet.getXXX())
qui permettent de récupérer le résultat contenu
dans une colonne sélectionnée.
On peut utiliser soit le numéro de la colonne
désirée, soit son nom avec l'accesseur. La
numérotation des colonnes commence à 1.
XXX correspond au type de la colonne. Le
tableau suivant précise les relations entre type
SQL, type JDBC et méthode à appeler sur l'objet
ResultSet.
Olivier Curé ­ UMLV [page 218 ]
Les types
Type SQL
Type JDBC
Méthode d'accès
char
String
getString()
varchar
String
getString()
integer
Integer
getInt()
double,
Double
getDouble()
float
Float
getDouble()
Date
Date
getDate()
Blob
Blob
getBlob()
Olivier Curé ­ UMLV [page 219 ]
Exemple
try {
while (rs.next()) {
System.out.println(rs.getString("NAME") + " – " + rs.getString("EMAIL"));
}
}
catch (SQLException e) {
System.err.println("Error browsing query results: " + e.getMessage());
}
Olivier Curé ­ UMLV [page 220 ]
Fermeture de la connexion
●
Objectif : Libérer les ressources
try {
resultSet.close();
connection.close();
}
catch (SQLException e) {
System.err.println("Error closing connection: " + e.getMessage());
}
Olivier Curé ­ UMLV [page 221 ]
Exemple 'SELECT'
import java.sql.*;
public class Query1 {
public Query1()
{
String url = "jdbc:mysql://localhost:3306/film"; // film est
le nom de la base de donne'es
Connection con;
String query = "SELECT director,nat from director;";
Statement stmt;
try {
Driver mySQLDriver = new org.gjt.mm.mysql.Driver();
con = DriverManager.getConnection(url,"o" ,"ol" );
System.out.println("Con = " + con);
stmt = con.createStatement();
Olivier Curé ­ UMLV [page 222 ]
Exemple 'SELECT' (2)
ResultSet rs = stmt.executeQuery(query);
while (rs.next()) {
System.out.println(rs.getString(1)+"
("+rs.getString(2)+")");
}
stmt.close();
con.close();
} catch(SQLException ex) {
System.err.println("SQLException: " + ex.getMessage());
}
}
public static void main(String args[])
{
Query1 query1 = new Query1();
}
}
Olivier Curé ­ UMLV [page 223 ]
Instruction SQL
paramétrée
●
●
●
La plupart des SGBD (dont Oracle) ne peuvent
analyser qu'une seule fois une requête exécutée
un grand nombre de fois
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 qui
hérite de l'interface Statement
Olivier Curé ­ UMLV [page 224 ]
Création d'une requête
paramétrée
PreparedStatement pstmt =
conn.preparedStatement("UPDATE emp SET sal=?
WHERE nom=?;");
●
●
●
●
Les '?' indiquent les emplacements des paramètres.
Les valeurs des paramètres sont données par les
méthodes setXXX(n,valeur).
On choisit la méthode setXXX suivant le type SQL de
la valeur que l'on veut mettre dans la requête.
C'est au développeur de passer une valeur Java
cohérente avec le type.
Olivier Curé ­ UMLV [page 225 ]
Requête paramétrée Exemple
PreparedStatement pstmt =
conn.preparedStatement("UPDATE emp SET sal=?
WHERE nom=?;");
for(int i=1; i<=10,i++)
{
pstmt.setDouble(i, salaire[i]);
pstmt.setString(i,nom[i]);
pstmt.executeUpdate();
}
●
On peut passer la valeur NULL avec setNull (n,type)
(type de la classe Types).
Olivier Curé ­ UMLV [page 226 ]
Avantages des requêtes
paramétrées
●
●
Traitement plus rapide si elles sont
utilisées plusieurs fois avec plusieurs
paramètres.
Amélioration de la portabilité
(indépendance des setXXX avec les
SGBD).
Olivier Curé ­ UMLV [page 227 ]
Téléchargement