JDBC

JDBC Java DataBase Connectivity.

... pour les TPs

1ère connection

Source de Connect1.java
import java.sql.*;
public class Connect1 {
  public static void main(String args[]) {
    try {
      Class.forName("com.mysql.jdbc.Driver");
    } catch(ClassNotFoundException e) {
      System.err.print("ClassNotFoundException: ");
      System.err.println(e.getMessage());
    }    
    try {
      Connection con = DriverManager.getConnection("jdbc:mysql://localhost/nosamisleschiens",
                                                   "toto", "secretoto");
	  Statement st = con.createStatement();
      String query = "SELECT * FROM chien";
      System.out.println("query : " +query);      
      ResultSet rs = st.executeQuery(query);
      while (rs.next()) {
        String nom = rs.getString("nom");
        String maitre = rs.getString("maitre");
        String aboie = rs.getString("aboiement");
        int nbPuces = rs.getInt("nombrePuces");
        System.out.println(nom + "|" + maitre + "|" +aboie+ "|" +nbPuces);
      }
      rs.close();
      con.close();      
    } catch(SQLException ex) {
      System.err.println("SQLException: " + ex.getMessage());
    }
  }
}
EXECUTION
$ java Connect1
query : SELECT * FROM chien
milou|tintin|ouah|4
rantanplan|averel|miam|26
medor|sarko|grrr|10
  • les lignes de la classe :
    • Le programme se connecte à la base nosamisleschiens sur la machine localhost avec le login toto et le mot de passe secretoto
    • puis crée une requête composée d'une instruction SQL
    • puis déclanche l'exécution de la requête et récupère la "table" résultat
    • extrait les informations de la table "résultat" dans une boucle de parcours de la table
    • ferme proprement la connection

Driver

EXECUTION
$ javac Connect1.java
$ java Connect1
ClassNotFoundException: com.mysql.jdbc.Driver
SQLException: No suitable driver

$ CLASSPATH=$CLASSPATH:/home/ferment/bin/mysql-connector-java-3.0.17-ga-bin.jar;
export CLASSPATH

$ java Connect1
query : SELECT * FROM chien
milou|tintin|ouah|4
rantanplan|averel|miam|26
medor|sarko|grrr|10
  • Un driver pour MySql a été ajouté dans un répertoire
  • le CLASSPATH reçoit son chemin

ResultSet

Source de Connect4.java
...   
    try {
      Connection con = DriverManager.getConnection("jdbc:mysql://localhost/nosamisleschiens",
                                     "toto", "secretoto");
	    Statement st = con.createStatement();
      String query = "SELECT * FROM chien";
      System.out.println("query : " +query+"\nchamp1|champ3|champ4");      
      ResultSet rs = st.executeQuery(query);
      while (rs.next()) {
        String nom = rs.getString(1);
        String aboie = rs.getString(3);
        int nbPuces = rs.getInt(4);
        System.out.println(nom + "|" +aboie+ "|" +nbPuces);
      }
...
EXECUTION
$ java Connect4
query : SELECT * FROM chien
champ1|champ3|champ4
milou|ouah|4
rantanplan|miam|26
medor|grrr|10
  • les lignes de la classe :
    • les valeurs dans les colonnes sont récupérées à partir du numéro de colonne

erreurs SQL

Source de Connect2.java
import java.sql.*;
public class Connect2 {
  public static void main(String args[]) {
    try {
      Class.forName("com.mysql.jdbc.Driver");
    } catch(java.lang.ClassNotFoundException e) {
      System.err.print("ClassNotFoundException: ");
      System.err.println(e.getMessage());
    }    
    try {
      Connection con = DriverManager.getConnection("jdbc:mysql://localhost/nosamisleschiens",
                                                  "toto", "secretoto");
	    Statement st = con.createStatement();
      String query = "SELECT chat FROM chien";
      System.out.println("query : " +query);      
      ResultSet rs = st.executeQuery(query);
      rs.close();
      con.close();      
    } catch(SQLException ex) {
      System.out.println("Exception SQL : ");
      while (ex != null) {
        System.out.println("Message = "+ex.getMessage()+"\nSQLState = "
                           +ex.getSQLState()+"\nErrorCode = "+ex.getErrorCode());
        ex.printStackTrace();
        ex = ex.getNextException();
      }
    }
  }
}
EXECUTION
$ java Connect2
query : SELECT chat FROM chien
Exception SQL : 
Message = Column not found message from server: "Unknown column 'chat' in 'field list'"
SQLState = S0022
ErrorCode = 1054
java.sql.SQLException: Column not found message from server: "Unknown column 'chat' in 'field list'"
        at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2001)
        at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1168)
        at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1279)
        at com.mysql.jdbc.MysqlIO.sqlQuery(MysqlIO.java:1225)
        at com.mysql.jdbc.Connection.execSQL(Connection.java:2278)
        at com.mysql.jdbc.Connection.execSQL(Connection.java:2225)
        at com.mysql.jdbc.Statement.executeQuery(Statement.java:1163)
        at Connect2.main(Connect2.java:16)
  • les lignes de la classe :
    • Y apas de chat chez les chiens !blabla

Résultats des méthodes executeXXX(requete_SQL)

Source de Connect3.java
....   
      String query = "SELECT COUNT(*) FROM chien";
      boolean etat = st.execute(query);
      System.out.println("query : " +query+" boolean resultat="+etat); 
      if (etat) {
        ResultSet resultSet = st.getResultSet();
        // ResultSet resultSet = st.executeQuery(query); etait plus direct !
        resultSet.next();
        System.out.println("count ="+resultSet.getInt(1));
      }
      query = "INSERT INTO chien VALUES(\"cerbere\",\"nicolas\",\"graouh\",666)";
      int nombre = st.executeUpdate(query);
      System.out.println("query : " +query+" nombre de lignes ajoutees = "+nombre);  
      query = "DELETE FROM chien WHERE nom = \"cerbere\"";
      nombre = st.executeUpdate(query);
      System.out.println("query : " +query+" nombre de lignes supprimees="+nombre); 
      con.close();      
....
EXECUTION
$ java Connect3
query : SELECT COUNT(*) FROM chien boolean resultat=true
count =3
query : INSERT INTO chien VALUES("cerbere","nicolas","graouh",666) nombre de lignes ajoutees = 1
query : DELETE FROM chien WHERE nom = "cerbere" nombre de lignes supprimees=1

MetaData

Source de Connect5.java
...
   Statement st = con.createStatement();
   String query = "SELECT * FROM chien";
   System.out.println("query : " +query);      
   ResultSet rs = st.executeQuery(query);
   ResultSetMetaData metadata = rs.getMetaData();
   for(int i = 1; i <= metadata.getColumnCount(); i++)
     System.out.println("colonne = "+i+" nom : "+metadata.getColumnName(i)
          +" Type SQL dans java.sql.Types : "+metadata.getColumnType(i)
          +" Nom du type SQL : "+metadata.getColumnTypeName(i)
          +" Classe java correspondante : "+metadata.getColumnClassName(i));
...
EXECUTION
$ java Connect5
query : SELECT * FROM chien
colonne = 1 nom : nom Type SQL dans java.sql.Types : 12 
  Nom du type SQL : VARCHAR Classe java correspondante : java.lang.String
colonne = 2 nom : maitre Type SQL dans java.sql.Types : 12 
  Nom du type SQL : VARCHAR Classe java correspondante : java.lang.String
colonne = 3 nom : aboiement Type SQL dans java.sql.Types : 12 
  Nom du type SQL : VARCHAR Classe java correspondante : java.lang.String
colonne = 4 nom : nombrePuces Type SQL dans java.sql.Types : 4 
  Nom du type SQL : INTEGER Classe java correspondante : java.lang.Integer
  • les lignes de la classe :
    • affiche les informations (méta-donnée) sur les colonnes du résultat

contrôle du curseur d'un ResultSet

Source de Connect6.java
...
   Statement st = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
                                      ResultSet.CONCUR_READ_ONLY);
      // createStatement() par defaut : ResultSet.TYPE_FORWARD_ONLY
   String query = "SELECT * FROM chien ORDER BY nombrePuces";
   System.out.println("query : " +query);      
   ResultSet rs = st.executeQuery(query);
   rs.last();
   int nombreLignes = rs.getRow();
   System.out.println("Ce ResultSet contient "+nombreLignes+" lignes.");
   do
     System.out.println("nom : "+rs.getString("nom")
               +" nombre de puces = "+rs.getString("nombrePuces"));
   while (rs.previous());
   rs.close();
...
EXECUTION
$ java Connect6
query : SELECT * FROM chien ORDER BY nombrePuces
Ce ResultSet contient 3 lignes.
nom : rantanplan nombre de puces = 26
nom : medor nombre de puces = 10
nom : milou nombre de puces = 4
  • les lignes de la classe :
    • la requete donne la liste des chiens classés par nombre de puces croissant.
    • la boucle d'affichage affiche du dernier au premier de cette liste

Transaction et Batch

Source de Connect7.java
...
   DatabaseMetaData metaData = con.getMetaData(); 
   if (metaData.supportsTransactions() 
               && metaData.supportsBatchUpdates()) {
     con.setAutoCommit(false);
     Statement st = con.createStatement();
     st.clearBatch(); 
     String query1 = "INSERT INTO chien VALUES(\"cerbere\",\"nicolas\",\"graouh\",666)";
     st.addBatch(query1);
     String query2 = "DELETE FROM chien WHERE nom = \"cerbere\"";
     st.addBatch(query2);
     int[] resultats = st.executeBatch();
     if ((resultats[0]>=0) && (resultats[1]>=0)) {
       con.commit();
       System.out.println("transaction reussie");
     } else {
       con.rollback();
       System.out.println("transaction echouee");
     }
     con.setAutoCommit(true);
   } else
     System.out.println("batch ou transaction non supportee");
...
EXECUTION
$ java Connect7
transaction reussie
  • les lignes de la classe :
    • Pour faire 2 requetes SQL en une seule transaction:
      • les 2 requetes sont regroupées dans un "batch"
      • selon le résultat de l'exécution du batch, on valide (commit) ou non (rollback) la transaction

exercices