Java II - 6-JDBC
Java II - 6-JDBC
Java II - 6-JDBC
JAVA II
¤ architecture 3/tiers :
Principe d'accès à une BDD
8
¤ 4. Exécuter la requête
¤ 6. Fermer la connexion
Etape 1: Charger le pilote
9
¨ Cette étape permet de préciser le type de driver que l'on veut utiliser. Elle n’est plus requise
depuis Java 6 :
¤ Dans Java SE 6.0 et versions ultérieures (JDBC 4.0 et versions ultérieures), le pilote est chargé
automatiquement.
¨ Java 5 et versions antérieures :
¤ On charge la classe de pilote uniquement. La classe possède un bloc d'initialisation statique qui crée
une instance et l'enregistre auprès de DriverManager :
try {
//remplacé par: Class.forName("com.mysql.cj.jdbc.Driver");
Class.forName("com.mysql.jdbc.Driver");
Class.forName("oracle.jdbc.driver.OracleDriver");
}catch (ClassNotFoundException cnfe) {
System.out.println("Error loading driver: " + cnfe);
}
¨ Tous les SGBD n'ont pas les mêmes types SQL (même pour les
types de base, il peut y avoir des différences importantes)
¨ Le driver JDBC traduit le type JDBC retourné par le SGBD en
un type Java correspondant
¤ le XXX de getXXX() est le nom du type Java correspondant au
type JDBC attendu
¤ chaque driver a des correspondances entre les types SQL du SGBD
et les types JDBC
¤ le programmeur est responsable du choix de ces méthodes
n SQLException générée si mauvais choix
¨ Le tableau suivant montre l’équivalence de types entre Java et
SQL:
Types de données JDBC/SQL
18
¨ Exemple :
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT nom, commission FROM employe");
while (rs.next()) {
nom = rs.getString(1);
commission = rs.getDouble(2);
if (rs.wasNull()) System.out.println(nom + ": n'a pas de commission");
else System.out.println(nom + " a " + commission + "euros de commission");
}
Accès aux méta-données
20
¨ JDBC permet de récupérer des informations
¤ sur le type de données que l'on vient de récupérer par un SELECT en utilisant l’interface
ResultSetMetaData.
¤ mais aussi sur la base elle-même en utilisant l’interface DatabaseMetaData.
¨ Interface ResultSetMetaData
¤ La méthode getMetaData() permet d’obtenir des informations sur les types de données du
ResultSet
¤ elle renvoie des instances de ResultSetMetaData
¤ on peut connaître entre autres :
n le nombre de colonne : getColumnCount()
n le nom d’une colonne : getColumnName(int col)
n le nom de la table : getTableName(int col)
n si un NULL SQL peut être stocké dans une colonne : isNullable()
Statement st = connexion.createStatement();
ResultSet rs = st.executeQuery("SELECT * FROM employe");
ResultSetMetaData rsmd = rs.getMetaData();
int nbColonnes = rsmd.getColumnCount();
for (int i = 1; i <= nbColonnes; i++) {
String typeColonne = rsmd.getColumnTypeName(i);
String nomColonne= rsmd.getColumnName(i);
System.out.println("Colonne " + i + " de nom "+ nomColonne +" de type "+ typeColonne);
}
Accès aux méta-données
21
¨ Interface DatabaseMetaData
¤ informations sur la base de données
¤ méthode getMetaData() de l’objet Connection
¨ La plupart des SGBD offre la possibilité de n'analyser qu'une seule fois une
requête
¨ JDBC permet de bénéficier de cette fonctionnalité
¨ L’objet PreparedStatement envoie une requête sans paramètres à la base de
données pour précompilation et spécifiera le moment voulu la valeur des
paramètres
¤ plus rapide qu’un Statement classique
n le SGBD n’analyse qu’une seule fois la requête (recherche d’une stratégie d’exécution
adéquate)
n pour de nombreuses exécutions d’une même requête SQL avec des paramètres
variables
¤ tous les SGBD n’acceptent pas les requêtes précompilées
¨ Avantages des PreparedStatement
¤ Traitement plus rapide si utilisés plusieurs fois avec plusieurs paramètres
¤ Amélioration de la portabilité car les méthodes setXXX() n’ont pas à tenir compte
des différences entre SGBD
¤ Exemple: les SGBD n’utilisent pas tous les mêmes formats de date ('JJ/MM/AA' ou
'AAAA-MM-JJ') ou de chaînes de caractères (pour les caractères d'échappement)
Requêtes pré-compilées
23
¨ Exemple :
Connection connexion = DriverManager.getConnection("jdbc:mysql://localhost/test", "root", "password");
connexion.setAutoCommit(false);
try {
Statement statement = connexion.createStatement();
statement.executeUpdate("INSERT INTO etudiants (nom, age, note) VALUES ('Ahmed', '18', '14.25')");
statement.executeUpdate("UPDATE etudiants SET note = '12,5' WHERE (nom = 'Ali')");
...
connexion.commit();
} catch (Exception e) {
try {
connexion.rollback();
} catch (SQLException sqle) {
// report problème
}
} finally {
try {
connexion.close();
} catch (SQLException sqle) { }
}
JNDI et BD dans le Web
29
<Context>
<Resource
name="jdbc/myDatabase"
driverClassName="org.apache.derby.jdbc.ClientDriver"
url="jdbc:derby:myDatabase"
type="javax.sql.DataSource"
username="someuser"
password="somepassword"
auth="Container"
maxActive="8"
/>
</Context>
Exemple
31
import java.sql.*;
public class ConnexionBD {
public Connection connexion;
public Statement instruction;
public ResultSet resultat, rs;
public ConnexionBD() {
try {
//Class.forName("com.mysql.jdbc.Driver").newInstance();
//Class.forName("com.mysql.jdbc.Driver"); //deprecated:remplacé par com.mysql.cj.jdbc.Driver
//Class.forName("com.mysql.cj.jdbc.Driver"); //plus besoin de charger le driver à partir de java 6
Connection connexion = DriverManager.getConnection("jdbc:mysql://localhost/test", "root", "pass");
instruction = connexion.createStatement();
//String url = "jdbc:mysql://localhost/test";
//String driver = "com.mysql.cj.jdbc.Driver";
//Class.forName(driver);
//Properties userInfo = new Properties();
//userInfo.put("user", "root");
//userInfo.put("password", "08111980");
//Connection connexion = DriverManager.getConnection(url, userInfo);
//instruction = connexion.createStatement();
} catch (Exception ex) {
System.err.println("Problème de pilote");
}
}
public void lire(String requete) {
try {
resultat = instruction.executeQuery(requete);
} catch (SQLException ex) {
System.err.println("Requète incorrecte "+requete);
}
}
Exemple
32
public void miseAJour(String requete) {
try {
instruction.executeUpdate(requete);
} catch (SQLException ex) {
System.err.println("Requète incorrecte "+requete);
}
}
public boolean suivant() {
try {
return resultat.next();
} catch (SQLException ex) {
return false;
}
}
public void arret() {
try {
connexion.close();
} catch (SQLException ex) {
System.err.println("Erreur sur l'arrêt de la connexion à la base de données");
}
}
}
import java.sql.SQLException;
public class TestConnexionBD {
public static void main(String[] args) throws SQLException {
ConnexionBD con = new ConnexionBD();
con.lire("SELECT * FROM etudiants");
while (con.suivant()){
System.out.println("nom "+con.resultat.getString("nom")+" age "+con.resultat.getInt("age"));
}
}
}