programmation dapplications bases de données avec java int
TRANSCRIPT
Programmation d’applicationsBases de données avec Java
INT
Bases de Données 2
Plan du document
Contexte slide 3 Programmer avec une BD slide 4 JDBC slide 7 Evolutions de JDBC slide 26
Ressources en ligne
http://mica/~oracle/IO21
Bases de Données 3
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 4
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
Programmer avec une BD
Bases de Données 5
Embedded SQLProgramme source (C+SQL)
Précompilation
Programme source Requêtes BD
sans cde SQL
compilation Traitement
code objet LibrairiesPlan d'exécution
Linkage Stockage
programme exécutable BD
Programmer avec une BD
DD
Bases de Données 6
Interfaces SQL LPGProgrammer avec une BD
Niveau d'interface
de programmation
Java Autres langages
Embedded SQL SQLJ C+SQL (Pro*C Oracle)
SQL/CLI JDBC OCI (Oracle)
PSM PL/SQL (Oracle) ou Java
Bases de Données 7
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 8
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 9
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 10
JDBC avec pilote Oracle (1)
AppliJava
Oracle
Client Serveur
Déploiement d’application difficile puisque avec middleware propriétaire sur le client
API JDBC
Ora*net
Ora*net
Ora*net
Ora*net
Pilote JDBC/Oracle
OCIOranet client
Bases de Données 11
JDBC avec pilote Oracle en Java (2)
AppliJava
Oracle
Client Serveur
Déploiement d ’application facile puisque sans middleware propriétaire sur le client
API JDBC
Ora*net
Ora*net
Ora*net
Ora*net
Trad. JDBC/OCI
Client Oranet
Pilote JDBC/Oracle
Bases de Données 12
Classes et interfaces du "paquage"java.sql
Driver Statement Connection ResultSet ResultSetMetaData DatabaseMetaData
PreparedStatement
CallableStatement
Java.lang.Object
Java.util.Date DriverManager DriverPropertyInfo Types
Date Time TimeStamp
Bases de Données 13
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 14
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 15
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 16
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 17
Execution d'une requête (1/2)
3 types d'executions : executeQuery : pour les requêtes qui retournent un ensemble
(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 18
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 19
Récupération des résultats (1/2)
executeQuery() 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
getXXX() où XXX représente le type de l'objet ou bien par un getObject suivi d’une conversion explicite
Pour les types longs, on peut utiliser des streams.
Bases de Données 20
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 21
Correspondance de type SQL/Java
Type SQL Type Java Méthoderecommandée
numeric Java.Math.BigDecimal Java.Math.BigDecimalGetBigDecimal()
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 22
Exemple de SQL dynamiqueclass 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 23
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 24
Exemple de MetaDataclass 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 25
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 26
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 27
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 28
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 29
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