L'accès à une base de données :

A partir de la version 1.1 du JDK, l'API JDBC (Java DataBase Connectivy) fait partie intégrante de la plate-forme Java. JDBC est un ensemble de classes et d'interfaces permettant de réaliser des connexions vers des bases de données et d'effectuer des requêtes. L'API JDBC est représentée par le package java.sql.

le package java.sql
Installer un driver
Connexion à une base de données
Requêtes de sélection
Requêtes de mises à jour
Déconnexion

Le package java.sql

Les principales interfaces  et quelques méthodes :

java.sql.DriverManager : Elle prend en charge le chargement des pilotes et permet de créer de nouvelles connexions à des bases de données. Elle tient à jour, la liste principale des pilotes JDBC recensés du système.

static public synchronized Connection getConnection(String url,
                String user, String password) throws SQLException ;
    // Etablit une connexion au système de codage de données
    // désigné par l'URL fourni. Le DriverManager recherche
    // ensuite dans sa liste l'instruction du pilote associé à cet URL.
java.sql.Connection : Elle représente une connexion à une base de données.
public abstract void close() throws SQLException ;
    // fermeture de la connexion.
public abstract Statement createStatement() throws SQLException ;
    // Génère un objet Statement associé à la connexion courante..
java.sql.Statement : C'est une classe que l'application emploie pour transmettre des instructions à la base, elle représente une requête SQL. La fermeture d'un Statement engendre la fermeture automatique des tous les ResultSet associés.
public abstract boolean execute() throws SQLException ;
    // permet d'exécuter une requête lorsque son contenu
    // est inconnu (sélection ou mise à jour)
    // renvoie true si l'exécution a permis de créer un ResultSet.
public abstract ResultSet executeQuery() throws SQLException ;
    // Exécute une requête et renvoie un ResultSet.
public abstract int executeUpdate() throws SQLException ;
    // Exécute une mise à jour et renvoie le nombre de rangée concernées
java.sql.ResultSet : Cette classe symbolise un ensemble de résultats dans la base de données et autorise l'accès aux résultats d'une requête rangée par rangée. Pendant le traitement de la requête, un ResultSet conserve un pointeur vers la rangée manipulée. L'application se déplace séquentiellement dans l'ensemble des résultats.
public  boolean getBoolean(int IndexColonne) throws SQLException ;
public  boolean getBoolean(String NomDeColonne) throws SQLException ;
public  Date getDate(int IndexColonne) throws SQLException ;
public  Date getDate(String NomDeColonne) throws SQLException ;
public  int getInt(int IndexColonne) throws SQLException ;
public  int getInt(String NomDeColonne) throws SQLException ;
public  long getLong(int IndexColonne) throws SQLException ;
public  long getLong(String NomDeColonne) throws SQLException ;
public  String getString(int IndexColonne) throws SQLException ;
public  String getString(String NomDeColonne) throws SQLException ;
public  float getFloat(int IndexColonne) throws SQLException ;
public  float getFloat(String NomDeColonne) throws SQLException ;
    // Chacune de ces méthodes renvoie la valeur de la colonne stipulée.
    // Il existe une méthode getXXX(...) pour chaque type de données
public boolean absolute(int row)  throws SQLException;
    // Si le paramètre est positif  le curseur se place la rangée
    // dont le numéro est donné en paramètre(absolute(1) est équivalent
    // à la méthode first(). Si le paramètre est négatif, le curseur  se déplace
    // relativement par rapport à sa position en reculant de "row" rangées.
    // (absolute(-2) entraine un recul de deux rangées du curseur.
public  boolean next() throws SQLException ;
    // Permet d'accéder à la rangée suivante dans le ResultSet,
    // Retourne true s'il reste au moins une rangée à traiter,
    // et false lorsque ce n'est pas le cas.
public boolean previous()  throws SQLException ;
    // JDBC 2.0 Déplace le curseur sur la rangée précédente du ResultSet.
    // Retourne true si le curseur est sur une rangée valide, false sinon.
public void beforeFirst() throws SQLException ;
    //  JDBC 2.0  Déplace le curseur avant la première rangée
    //  N'a pas d'effet, si le ResultSet ne contient rien.
public boolean first() throws SQLException;
    // JDBC 2.0 Déplace le curseur sur la première rangée
     //retourne true si le curseur est sur une rangée valide, false sinon
public void afterLast() throws SQLException ;
    // JDBC 2.0   Déplace le curseur juste après la dernière rangée.
    //  N'a pas d'effet, si le ResultSet ne contient rien.
public boolean last() throws SQLException ;
    // JDBC 2.0 Déplace le curseur sur la dernière rangée
     //retourne true si le curseur est sur une rangée valide, false sinon
public int getRow() throws SQLException ;
    // JDBC 2.0  Donne le numéro de la rangée courante,
    // ou 0 s'il n'y a pas de rangée courante sélectionnée.
    // La première rangée est numéroté 1, la deuxième 2, ...
public void moveToInsertRow()  throws SQLException
    // JDBC 2.0 Insère une ligne dans le ResultSet et place
     // le curseur sur cette rangée.
public   void insertRow() throws SQLException ;
    // JDBC 2.0 Insère le contenu de la rangée insérée
    // dans le ResultSet et la base de données.
public void deleteRow() throws SQLException
    // JDBC 2.0 Supprime la rangée courante du ResultSet
    // dans la base de données.
public void updateRow() throws SQLException
     // JDBC 2.0 Modifie une à plusieurs colonnes de la
    // rangée en cours (après utilisation de méthodes
    // updateXXX(...) )
public void updateString(String NomCol, String x)  throws SQLException
    // Permet de modifier la valeur d'une colonne
    // Il existe une méthode updateXXX(...) pour chaque type de données

Installer un driver

Il existe un driver spécifique pour chaque SGBD (système de gestion de bases de données : Access, Oracle, Informix, ...). Chaque produit a un pilote JDBC adapté, dont certains sont souvent commercialisés par les éditeurs.

Quatre types de drivers peuvent être distingués :

Nous allons partir de l'exemple d'une base de données ACCESS, à laquelle nous accèderons au moyen d'un pont ODBC.

Pour paramétrer une source de données ODBC :

1. Ouvrir le Panneau de configuration,
2. Sélectionner l'Administrateur de source de données ODBC,
3. Cliquer sur l'onglet DNS Système,
4. Cliquer sur le bouton Ajouter,
5. Sélectionner dans la liste le pilote Microsoft Access driver (*.mdb), puis cliquer sur le bouton
    Terminer,
6. Indiquer un nom pour la source de données (bdVoyage de préférence sans caractère spécial, ni espace), une description (non obligatoire, mais recommandée),

7. Cliquer sur le bouton Sélectionner pour définir la localisation de la base, puis sur Ok, et fermer la fenêtre de l'administrateur de source ODBC.

Cette base contient les tables suivantes :
T_Voyages(NoVoyage, LibVoyage, DateDebut, Duree, NbInscrits, #NoDestination)
T_Destinations(NoDestination, LibDestination)

avec : soulignés <- clés primaires
            #<- Clé étrangère

Connexion à une base de données

Dans une applet ou une application java qui utilise une base de données, la mention de l'URL de la base est obligatoire :

String NomUrl = "jdbc:SousProtocole:SourceDeDonnées";

Dans notre exemple, l'URL de la base de données est la suivante :

 
String url = "jdbc:odbc:bdvoyage";
Pour accéder à une source de données, il est nécessaire de disposer d'un pilote JDBC. Dans notre cas, nous chargeons le pilote jdbc-odbc de SUN, sinon dans le cas d'un driver propriétaire la documentation de l'éditeur du driver précise son nom : "jdbc.NomDriver". Cette instruction charge le driver, en crée une instance et l'enregistre.

Dans notre exemple :

 
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Dès qu'un driver  a reconnu le gestionnaire de base de données correspondant à l'URL fournie, il lance une connexion à la base et utilise le nom d'utilisateur et le mot de passe indiqués. L'établissement de la connexion se fait selon le code suivant :

Connection con = DriverManager.getConnection(NomUrl,"NomUtilisateur","MotDePasse");

Dans notre exemple, l'accès concerne une base Access où les noms d'utilisateurs ne sont pas gérés :

 
Connection con = null;
 con = DriverManager.getConnection(url,"","");

Les requêtes de sélection :

L'objet Connection créé va permettre d'interagir avec la base. Pour réaliser des requêtes de sélection, un objet de type Statement doit être généré.

Statement symbolise une instrution SQL.

 
Statement requete = con.createStatement();
Le résultat d'une requête est récupéré au moyen d'un objet de type ResultSet. Cette interface permet d'accéder aux données extraites grâce à la requête.
 
ResultSet resultat = requete.executeQuery("select * from T_destinations");
Après la requête, le curseur est positionné juste avant la première ligne du résultat, la méthode next() permet d'avancer d'enregistrements en enregistrements séquentiellement.
 
resultat.next()
Pour récupérer les données dans chaque colonne, l'interface ResultSet propose plusieurs méthodes adaptées aux types des données récupérées : getString(NumColonne), getInt(NumColonne), getDate(NumColonne), ...
 
System.out.println(resultat.getInt(1)+"  "+resultat.getString(2));
EXEMPLE d'une REQUETE de SELECTION :
 
import java.sql.*;
import java.io.*;

public class essaiVoy {
 public static void main(String args[]) {
   String url = "jdbc:odbc:bdvoyage";
   Connection con = null;
   try {Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
        con = DriverManager.getConnection(url,"","");
        Statement requete = con.createStatement();
        ResultSet resultatDest = requete.executeQuery("select * from T_destinations");
        while (resultat.next()) {
                       System.out.println(resultatDest.getInt(1)+"  "+resultatDest.getString(2));
                       };
       }
  catch(Exception e) {  System.out.println("Exception");  }
  finally {
     try {con.close();}
    catch(SQLException e) {e.printStackTrace();}
    }
}
}

Exemples de mouvements de curseur (JDK 1.2) :

 
resultatDest.beforeFirst();    // Positionnement avant le premier enregistrement
     while ( rs.next()) { // boucle jusqu'après la dernière rangée
             System.out.println(resultatDest.getLong("NoDestination") +
                                " " + resultatDest.getString("LibDestination"));
     }
resultatDest.afterLast(); // positionnement après la dernière rangée
     while (resultatDest.previous()) { // boucle jusqu'avant la première rangée
             System.out.println(resultatDest.getLong("NoDestination") +
                                " " + resultatDest.getString("LibDestination"));
     }

Les requêtes de mises à jour :

La mise à jour d'une base de données peut être effectuée par le biais d'une requête SQL de type UPDATE, INSERT ou DELETE à partir de la méthode executeUpdate("Requête") sur un objet Statement. Le résultat renvoyé par l'exécution de la requête indiquera le nombre de lignes mises à jour dans la base, contrairement à une requête de sélection qui renvoie un ResultSet.
 
Statement s = con.createStatement();
int  NbIns ;
NbIns = s.executeUpdate("INSERT INTO T_Destinations (NoDestination,LibDestination) VALUES (16,"NOUVELLE CALEDONIE") ") ;
System.out.println(NbIns+" ligne insérée");
Si un ResultSet autorise la modification du résultat qu'il contient, trois méthodes peuvent être utilisées : updateRows(), deleteRows(), et insertRows(). Ces mises à jours sont effectives dans le ResultSet et dans la base de données.

 L'exemple suivant montre la modification de la première rangée d'un ResultSet qui contient tous les enregistrement de la table T_Voyages :.

 
resultatVoy.first();
// la valeur située dans la colonne 2 (libellé du voyage) est modifiée
resultatVoy.updateString(2, "Les pyramides d'Egypte");
// La valeur contenue dans la colonne intitulée Duree est modifiée
resultatVoy.updateInt("Duree",10); 
resultatVoy.updateRow();
 L'exemple qui suit montre la suppression de la cinquième rangée d'un ResultSet, cette suppression est répercutée sur la base :
 
resultatVoy.absolute(5); // positionnement sur la rangée 5
resultatVoy.deleteRow(); // Suppression de la rangée en cours
L'exemple suivant montre l'insertion d'une ligne dans le ResultSet, l'affectation de valeurs dans celle-ci, et la mise à jour dans la base de données :
 
resultatPays.moveToInsertRow(); // insertion d'une rangée vide
 resultatPays.updateLong(1, 14);
resultatPays.updateString(2, "Liban");
resultatPays.insertRow();
 resultatPays.first();

Déconnexion :

La méthode close() permet de libérer les ressources prises par la création d'objets de type ResultSet, Statement, et Connection. Elle existe pour chacune de ces interfaces. Elle est le plus souvent employée pour une Connection, car elle libère en même temps toutes les ressources qui lui sont associées.