Transparents

publicité
Programmation d’applications
Bases de données avec Java
INT
Plan du document
 Contexte
 Programmer avec une BD
 JDBC
 Evolutions de JDBC
slide 3
slide 4
slide 7
slide 26
 Ressources en ligne
http://mica/~oracle/IO21
Bases de Données
2
Contexte
 Limites du SQL interactif :
 Absence
de structure de contrôle
 Absence de variable
 Pas de "calcul" sur les données
  Adopter un langage de type procédural
 Limites des langages de programmation sur les
entrées/sorties
 Besoin de coupler SQL avec des langages de
programmation
Bases de Données
3
Programmer avec une BD
Interfaces SQL Lang. Prog.
 Embedded SQL :
 Précompilé
 Dépendant du SGBD cible
 Problème

2 systèmes de types, 2 styles de programmation, pas de débogage sur le
source
 SQL/CLI :
 Bas niveau  compilé uniquement
 Interface universelle SGBD SQL normalisée par l'ISO
 Pas implémentée par les vendeurs (Oracle implante Oracle Call Interface)
 PSM (Persistent Stored Modules) :
 Langages propriétaires PL/SQL pour Oracle (bientôt Java)
 "Routines"SQL
Bases de Données
4
Programmer avec une BD
Embedded SQL
Programme source (C+SQL)
DD
Précompilation
Programme source
Requêtes BD
sans cde SQL
compilation
code objet
Traitement
Librairies
Plan d'exécution
Linkage
Stockage
programme exécutable
BD
Bases de Données
5
Programmer avec une BD
Interfaces SQL LPG
Niveau d'interface Java
de programmation
Embedded SQL SQLJ
Autres langages
SQL/CLI
JDBC
OCI (Oracle)
PSM
PL/SQL (Oracle) ou Java
Bases de Données
C+SQL (Pro*C
Oracle)
6
JDBC
 API Java pour manipuler des relations via SQL
(dans des fichiers locaux ou via un SGBD)
 Une seule API uniforme (même niveau que
SQL CLI de X/open)
 Indépendance / SGBD cible (via des pilotes)
 Code portable de bout en bout
 Pas forcément construit au dessus de ODBC
Bases de Données
7
Pilotes JDBC
 JDBC non supporté en natif par les SGBD du
commerce (ou les systèmes de fichiers)
 Transformations des appels JDBC en appels natifs
 Un pilote pour chaque SGBD
 4 catégories de pilotes en fonctions de :

La présence ou non de pilote SGBD (non java) sur le client
 Protocole de communication entre le client Java et le serveur
Bases de Données
8
Fonctions possibles d'un pilote
 Dédié à un SGBD (peut être fourni par l'éditeur du




SGBD ou une société tierce)
Fournir une implémentation des interfaces Java de
l'API JDBC
Traduire les appels à l'API JDBC en appels vers une
API native d'un SGBD (Oracle par exemple)
Eventuellement peut offrir des fonctions d'accès distant
au SGBD
Si écrit en Java peut être téléchargeable (déploiement
facile)
Bases de Données
9
JDBC avec pilote Oracle (1)
Client
Serveur
Appli
Java
API JDBC
OCI
Oranet client
Ora*net
Pilote JDBC/Oracle
Oracle
Déploiement d’application difficile puisque avec
middleware propriétaire sur le client
Bases de Données
10
JDBC avec pilote Oracle en Java (2)
Client
Serveur
Appli
Java
API JDBC
Client Oranet
Ora*net
Trad. JDBC/OCI
Oracle
Pilote JDBC/Oracle
Déploiement d ’application facile puisque sans
middleware propriétaire sur le client
Bases de Données
11
Classes et interfaces du
"paquage"java.sql
Driver
Statement
Connection
ResultSet
ResultSetMetaData
DatabaseMetaData
PreparedStatement
CallableStatement
Java.lang.Object
Java.util.Date
Date
Time
DriverManager
DriverPropertyInfo
Types
TimeStamp
Bases de Données
12
Principes de programmation
 Quel que soit le gestionnaire de BD considéré, les
phases de l’interaction sont identiques :

Charger le Driver
 Connexion à la base
 Création d'un Statement (ou PreparedStatement)
 Exécution de la requête (executeUpdate ou executeQuery)
 Récupération des résultats (ResultSet)
 Gestion transactionnelle (commit/abort)
Bases de Données
13
Connexion JDBC
 Classe java.sql.Connection
 URL d’une source de données
jdbc:<subprotocol>:<subname>
jdbc:oracle:oci8:@ORTHOSE
jdbc:oracle:thin:@mica:1521:IOBD
jdbc:msql//athens.com:4333/db_test
Bases de Données
14
Connexion à la base (suite)
import java.sql.*;
Class.forName("oracle.jdbc.driver.OracleDriver");
chargement dynamique de la classe implémentant le pilote Oracle
String dburl = "jdbc:oracle:thin:@mica:1521:IOBD";
construction de l’url pour Oracle INT
Connection conn = DriverManager.getConnection(dburl, "toto",
"titi");
connexion à l’url avec un (user, passwd)=(toto, titi)
Bases de Données
15
Création d'un Statement
 Un objet Statement symbolise une instruction SQL
 3 types de statement :
 Statement
: requêtes simples
 PreparedStatement : requêtes précompilées
 CallableStatement : procédures stockées
 Création d'un Statement :
Statement stmt = conn.createStatement();
Bases de Données
16
Execution d'une requête (1/2)
 3 types d'executions :
: pour les requêtes qui retournent un ensemble

executeQuery
(SELECT)

executeUpdate

: pour les requêtes INSERT, UPDATE, DELETE,
CREATE TABLE et DROP TABLE
execute : pour quelques cas rares (procédures stockées)
Bases de Données
17
Execution d'une requête (2/2)
 Execution de la requête :
String myQuery = "SELECT nom, adresse " +
"FROM client " +
"WHERE (nom=’Durand') " +
"ORDER BY nom";
ResultSet rs = stmt.executeQuery(myQuery);
Bases de Données
18
Récupération des résultats (1/2)
renvoit un ResultSet
 Le RS se parcourt itérativement ligne par ligne
 Les colonnes sont référencées par leur numéro ou par leur nom
 L'accès aux valeurs des colonnes se fait par les méthodes

executeQuery()


où XXX représente le type de l'objet
ou bien par un getObject suivi d’une conversion explicite
getXXX()
 Pour les types longs, on peut utiliser des streams.
Bases de Données
19
Récupération des résultats (2/2)
java.sql.Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM Table1");
while (rs.next())
{
// print the values for the current row.
int i = rs.getInt("a");
String s = rs.getString("b");
byte b[] = rs.getBytes(3);
System.out.println("ROW = " + i + " " + s + " " +
b[0]);
}
Bases de Données
20
Correspondance de type SQL/Java
Type SQL
Type Java
Méthode
recommandée
numeric
Java.Math.BigDecimal
Java.Math.BigDecimal
GetBigDecimal()
integer
Integer
int getInt()
float
Double
double getDouble()
char, varchar
String
String getString()
date
Java.sql.Date
Java.sql.Date getDate()
Bases de Données
21
Exemple de SQL dynamique
class Employe {
...
public static int updateEmploye(int num, String nom) throws SQLException,
ClassNotFoundException {
Class.forName("oracle.jdbc.driver.OracleDriver");
String dburl = "jdbc:oracle:thin:@mica:1521:ENSE";
Connection conn = DriverManager.getConnection(dburl, "toto", "titi");
conn.setAutoCommit(false);
PreparedStatement pstmt = conn.preparedStatement("UPDATE Employe SET
salary=?, name=?, WHERE numemp=?");
psmt.setNull(1); psmt.setString(2, nom); psmt.setInt(3, num);
int nbLignesModifiees = psmt.executeUpdate();
if (nbLignesModifiees == 1) conn.commit(); else conn.rollback();
}
Bases de Données
22
Accès aux méta-données
 La méthode getMetaData() permet d'obtenir les méta- données
d'un ResultSet.
 Elle renvoit des ResultSetMetaData.
 On peut connaître :



Le nombre de colonne : int getColumnCount()
Le nom d'une colonne : String getColumnName(int col)
Le type d'une colonne : int getColumnType(int col)


l'entier peut être comparé aux constantes CHAR, VARCHAR, DOUBLE,
DATE, INTEGER
...
Bases de Données
23
Exemple de MetaData
class HTMLResultSet {
private ResultSet rs;
public HTMLResultSet (ResultSet rs){this.rs=rs;}
public String toString() {
StringBuffer out = new StringBuffer(); out.append("<TABLE>");
ResultSetMetaData rsmd=rs.getMetaData();
int numcols=rsmd.getColumnCount();
out.append("<TR>");
for (int i=0;i<numcols;i++) {
out.append("<TH>").append(rsmd.getColumnName(i));
}
out.append("</TR>");
...
}
Bases de Données
24
JDBC et la sécurité
 Respecte les principes sécurité de Java
 Application et trusted applets :
 accès
bases locales et serveur BD
 Untrusted applets ou untrusted JDBC driver
 connexion
seulement au site de chargement
Bases de Données
25
Evolution de JDBC
 JDBC 1.0 (janvier 1996)
 JDBC 2.0 (Mars 1998)
 JDBC 2.1 (2000)
 Extensions de JDBC 2.x







parcours avant/arrière d’un ResultSet
mise à jour depuis un ResultSet
batch de plusieurs ordres SQL
support des types SQL3
validation 2 phases via interface XA de l'XOPEN
notion de DataSource et utilisation de JNDI
pool de connexion, cache sur le client
Bases de Données
26
SQLJ
 Initiative de plusieurs éditeurs (Oracle, IBM, ...)
 Offre une interface de plus haut niveau que
JDBC (moins de code à écrire)
 Permet d’analyser le code SQL à la compilation
et donc de détecter des erreurs
 Peut se mixer avec du JDBC (pas de SQL
dynamique p.e dans SQLJ)
 SQLJ compilé en JDBC
Bases de Données
27
Exemples SQLJ
public static void updateDuration(String projName, int numDays) throws
SQLException {
#sql {UPDATE projects SET duration=duration+:numDays WHERE
id=:projName};
#sql {COMMIT};
}
public static voidlistOpenProjects() throws SQLException {
ProjIter projs=null; // déclaration de l'instance d'itérateur
#sqlprojs={SELECT start_date, name FROM projects };
while(projs.next()) {
System.out.println("Projet "+ projs.name() + "commence le
"+projs.start_date());
}
projs.close(); }
Bases de Données
28
Java Blend
 Génération automatique de classes Java à partir
d’une BD relationnelle
 Eventuellement dans les deux sens
 Primitives de chargement / sauvegarde
 Souvent du cache en plus
 De nombreux éditeurs présents sur ce segment
Bases de Données
29
Téléchargement