Documents
Resources
Learning Center
Upload
Plans & pricing Sign in
Sign Out

J2EE_Chapitre3

VIEWS: 2 PAGES: 11

									A. Zribi, H. Maatallah, M. R. Haddad, A. Maatig




                                                                      Chapitre 3:

       Connexion à une base de données
                            L’API JDBC


1. Introduction

    1.1.    Rappel sur les bases de données

    Une base de données est une entité dans laquelle il est possible de stocker des données
de façon structurée et avec le moins de redondance possible. Ces données doivent pouvoir
être utilisées par des programmes, par des utilisateurs différents. Ainsi, la notion de base de
données est généralement couplée à celle de réseau, afin de pouvoir mettre en commun ces
informations, d'où le nom de base. On parle généralement de système d'information pour
désigner toute la structure regroupant les moyens mis en place pour pouvoir partager des
données. On parle de base de données relationnelle si celle-ci est structurée suivant les
principes de l’algèbre relationnelle. En effet, elle est composée d’un ensemble de tables ou
de relations.

   Afin de pouvoir contrôler les données ainsi que les utilisateurs, le besoin d'un système de
gestion s'est vite fait ressentir. La gestion de la base de données se fait grâce à un système
appelé SGBD (système de gestion de bases de données). Le SGBD est un ensemble de
services (applications logicielles) permettant de gérer les bases de données, c'est-à-dire :

   •  permettre l'accès aux données de façon,
   • autoriser un accès aux informations à de multiples utilisateurs en assurant la sécurité
     et l’intégrité des données,
   • manipuler les données présentes dans la base de données (insertion, suppression,
     modification).

   On appelle transaction toute unité logique de traitement qui, appliquée à un état
cohérent de la base de données, restitue un nouvel état cohérent mais modifié de la base.

    Le langage SQL (Structured Query Language) peut être considéré comme le langage
d’accès normalisé aux bases de données. Il est aujourd’hui supporté par la plupart des
produits commerciaux que ce soit par les systèmes de gestion de bases de données micro
tel que ‘Access’ ou par les produits plus professionnels tels que Oracle. Il a fait l’objet de

                                                                                             1
A. Zribi, H. Maatallah, M. R. Haddad, A. Maatig

plusieurs normes ANSI/ISO dont la plus répandue aujourd’hui est la norme SQL2 qui a été
définie en 1992.

    Le succès du langage SQL est dû essentiellement à sa simplicité et au fait qu’il s’appuie
sur le schéma conceptuel pour énoncer des requêtes en laissant le SGBD responsable de la
stratégie d’exécution. Le langage SQL propose un langage de requêtes ensembliste et
assertionnel. Néanmoins, le langage SQL ne possède pas la puissance d’un langage de
programmation : entrées/sorties, instructions conditionnelles, boucles et affectations. Pour
certains traitements il est donc nécessaire de coupler le langage SQL avec un langage de
programmation plus complet.

   De manière synthétique, on peut dire que SQL est un langage relationnel, il manipule
donc des tables (i.e. des relations, c’est-à-dire des ensembles) par l’intermédiaire de
requêtes qui produisent également des tables.

   Open Database Connectivity (ODBC) est interface conçue par Microsoft pour l’accès
aux base de données SQL.

    1.2.    JDBC : Java DataBase Connectivity

    JDBC est une API d’accès aux systèmes de gestion de bases de données relationnelles
qui permet d’exécuter des requêtes SQL au sein d’un programme Java et de récupérer les
résultats. C’est de plus une tentative de standardiser l’accès aux bases de données car l’API
est indépendante du SGBD choisi, pourvu que le pilote JDBC existe pour ce SGBD, et qu’il
implémente les classes et interfaces de l’API JDBC.

    Ainsi, JDBC rend l’application indépendante du SGBD utilisé. Le lien avec un SGBD
spécifique est réalisé à l’aide de pilotes (drivers). Ces derniers sont fournis sous la forme de
classes Java. Pour récapituler, et comme présenté dans la figure 3.1, JDBC permet à une
même application, prenant en paramètres le nom du driver et la localisation de la base,
d’interroger une même base de données supportée par des SGBDs différents.




                                         Pilote JDBC (driver)




               Fig. 3.1. Architecture générale d’une application utilisant l’API JDBC


                                                                                              2
A. Zribi, H. Maatallah, M. R. Haddad, A. Maatig

2. JDBC et les architectures multiniveaux

    2.1.    Architecture à 2 niveaux

    Comme le montre la figure 3.2, dans une architecture client-serveur à 2 niveaux, un
programme client accède directement à une base de données sur une machine distante (le
serveur) pour échanger des informations, via des commandes SQL JDBC automatiquement
traduites dans le langage de requêtes propre à au SGBD.




                           Fig. 3.2. Architecture client serveur à 2 niveaux

    Le principal avantage de ce type d’architecture est qu’en cas de changement de SGBD, il
n’y a qu’à mettre à jour ou changer le driver JDBC du coté client. Cependant, pour une
grande diffusion du client, cette architecture devient problématique, car une telle modification
nécessite la mise à jour de chaque client.

    2.2.    Architecture à 3 niveaux

   Dans une architecture 3 niveaux, un programme client n’accède pas directement à la
base de données, mais à un serveur d’application qui fait lui-même les accès à la base de
données.




                           Fig. 3.3. Architecture client serveur à 3 niveaux

     Moyennant cette architecture, il est possible de gérer plus efficacement les connexions
au niveau du serveur d’application et d’optimiser les traitements. En plus, contrairement à
l’architecture à 2 niveaux, le changement du SGBD ne nécessite pas une mise à jour des
drivers sur tous les clients, mais seulement sur le serveur d’application.


                                                                                              3
A. Zribi, H. Maatallah, M. R. Haddad, A. Maatig

3. Etapes de conception d’une application utilisant JDBC

Les étapes généralement rencontrées pour effectuer un traitement avec une base de donnée
moyennant l’API JDBC sont

 1.   Chargement du driver correspondant au SGBD ciblé
 2.   Ouverture d'une connexion vers la base de données
 3.   Création d'une requête (Statement)
 4.   Exécution de la requête
 5.   Accès aux résultats de la requête
 6.   Accès aux méta-données (des résultats, de la connexion, etc.)
 7.   Gestions des erreurs (exceptions et warnings)
 8.   Libération des ressources (fermeture de la connexion, etc.)

4. La notion de Driver

    Un pilote ou driver JDBC est un "logiciel" qui permet d'établir une connexion entre un
programme java et un SGBD. Ce "logiciel" est en fait une implémentation de l'interface
Driver, du package java.sql.

    Il existe 4 types de drivers JDBC qui se différencient par leur implémentation (notamment
par l'utilisation ou non de méthodes natives). On notifie également que les drivers sont pris
en charge par la classe DriverManager.




          Fig. 3.4. Exemples de connexion JDBC avec SGBD utilisant différents drivers
                                                                                           4
A. Zribi, H. Maatallah, M. R. Haddad, A. Maatig

     Les drivers JDBC sont disponibles sous forme de classes java (implémentant
java.sql.Driver) contenues dans des fichiers JAR (Java ARchive). L'installation est donc
triviale, il suffit que le jar soit présent sur le disque dur et disponible dans le CLASSPATH
durant la compilation/exécution. La principale source pour trouver un driver se trouve sur le
site de Sun : http://servlet.java.sun.com/products/jdbc/drivers

    4.1.    Le pont JDBC-ODBC




                         Fig. 3.5. Architecture utilisant le pont JDBC-ODBC

   Comme illustré dans la figure 3.5, le pont JDBC-ODBC s’utilise avec ODBC et un pilote
ODBC spécifique pour la base à accéder. Cette solution fonctionne très bien sous Windows.
C’est la solution idéale pour des développements avec exécution sous Windows d’une
application locale. Ceci dit, cette solution présente plusieurs inconvénients :

   •    La multiplication du nombre de couches rend complexe l’architecture et détériore les
        performances,
   •    Lors du déploiement, ODBC et sont pilote doivent être installés dans tous les postes
        où l’application sera exécutée,
   •    La partie native (ODBC et son pilote) rend l’application moins portable et dépendant
        d’une plateforme.

    4.2.    Native-API partly-Java driver

    Dans ce cas de figure, un pilote écrit en Java appelle l’API native de la base de données.
Ce type de pilote convertie les ordres JDBC pour appeler directement les APIs de la base de
données. Il est de ce fait nécessaire de fournir au client l’API native de la base de données.
Elles sont généralement en C ou en C++.




                 Fig. 3.6. Architecture utilisant l’API native de la base de données
                                                                                            5
A. Zribi, H. Maatallah, M. R. Haddad, A. Maatig

    4.3.    JDBC-Net pure Java driver

    Comme illustré dans la figure 3.7, ce driver utilise un protocole réseau spécifique pour
dialoguer avec un serveur intermédiaire. Un serveur dédié reçoit les messages par ce
protocole et dialogue directement avec la base de données. Ce type de driver peut être
facilement utilisé par une applet, mais dans ce cas, le serveur intermédiaire doit
obligatoirement être installé sur la machine contenant le serveur Web.




      Fig. 3.7. Architecture utilisant un serveur intermédiaire pour la connexion à la base de
                                             données

    4.4.    Native-protocol pure Java driver

    Ce type de driver, écrit en Java, appelle directement le SGBD. Ils sont fournis par
l’éditeur de la base de données. Ce type de driver est la solution idéale tant au niveau de la
simplicité que des performances et du déploiement.




        Fig. 3.8. Architecture dans laquelle le driver se connecte directement à la base de
                                            données




5. Chargement du driver en mémoire

    Utiliser la méthode Class.forName, qui aura pour effet d'enregistrer le Driver auprès du
DriverManager. N'oubliez pas de vérifier que le jar contenant le driver est bien dans le
classpath.

    On notifie également que la méthode Class.forName(String driver) permet de lever une
exception de type ClassNotFoundException si il y a une erreur lors du chargement du
driver.


                                                                                                 6
A. Zribi, H. Maatallah, M. R. Haddad, A. Maatig

   Voici un exemple d’appel d’un driver proposé par Sun pour se connecter à une base de
données via ODBC (sun.jdbc.odbc.JdbcOdbcDriver) :

Try {
     Class.forName(“sun.jdbc.odbc.JdbcOdbcDriver”);
} catch (ClassNotFoundException e){
     System.out.println("La classe n'a pas été trouvée");
   }

        Pour se connecter à une base en utilisant un driver spécifique, la documentation du
driver fourni le nom de la classe à utiliser. Par exemple, si le nom de la classe est
package.driverx, le chargement du driver se fera avec le code suivant :

Class.forName(“package.driverx”);


6. Etablir une connexion avec la base de données

     La connexion à une base de données de fait par le biais de l’instanciation d’un objet de
l’interface Connection. Elle représente une session de travail avec une base de données.

       L’interface Connection utilise les méthodes getConnection() de la classe
DriverManager pour établir la connexion avec la base de données. Pour cela, on passe l’url
de la base de données en paramètre à la méthode. Les méthodes getConnection() peuvent
lever une exception de la classe java.sql.SQLException.

        La création d’une connexion simple se fait grâce à la méthode suivante

Public static Connection getConnection(String url) throws SQLException;


        Ainsi, l’appel est le suivant

Try {
     Connection connect = DriverManager.getConnection(url);
} catch (SQLException e){
     System.out.println("La connexion n’est pas établie");
   }

       La création d’une connexion avec un nom d’utilisateur et un mot de passe se fait à
travers la fonction :

Public static Connection getConnection(String url, String login, String
password) throws SQLException;

       A la place de ‘‘login’’ il faut mettre le nom d’utilisateur qui se connecte à la base et
mettre sont mot de passe dans ‘‘password’’.
       L’interface Connection dispose de plus de méthodes permettant de fermer la
connexion ainsi que de teste son état :
Public void close() throws SQLException;
Public boolean isClosed() throws SQLException;
                                                                                              7
A. Zribi, H. Maatallah, M. R. Haddad, A. Maatig

7. Traitement des requêtes SQL

        Pour traiter une requête SQL, on dispose de plusieurs objets capables d’envoyer
celle-ci à la base de données :
   • Statement : objet utilisé pour l’exécution d’une requête SQL statique retournant les
      résultats qu’elle produit,
   • PreparedStatement : utilisé lorsqu’il est nécessaire d’exécuter une requête plusieurs
      fois, avec des paramètres différents,
   • CallableStatement : objet utilisé pour appeler une procédure stockée.



    7.1.    L’interface Statement : les requêtes simples

      L’objet Statement représente une instruction de traitement SQL. Il est créé par
l’intermédiaire d’une instance de connection par la méthode :

Public Statement createStatement() throws SQLException;

Exemple:

Try {
      Statement state = connect.createStatement();
} catch (SQLException e){
...
    }

Cet objet est pourvu de méthodes permettant de faire exécuter:
   • Une requête SQL de consultation (SELECT), retournant les résultats de celle-ci :
Public ResultSet executeQuery(String sql) throws SQLException ;

    •   Une requête SQL de modification (UPDATE, DELETE, INSERT, CREATE, DROP) ne
        renvoyant que le nombre d’occurrences affectées par celle-ci :
Public int executeUpdate(String sql) throws SQLException ;

    •   Un lot de requêtes, renvoyant un tableau d’entiers correspondant au résultat de la
        requete :
Public int[] executeBatch() throws SQLException ;

        Utilisée conjointement avec les méthodes
Public void addBatch(String sql) throws SQLException ;
Public void clearBatch() throws SQLException ;

Exemple 1:
Try {
      ResultSet resultat = state.executeQuery(“SELECT DISTINCT nom FROM
eleves ORDER BY nom;”);
} catch (SQLException e){
...
    }


                                                                                        8
A. Zribi, H. Maatallah, M. R. Haddad, A. Maatig

Ce traitement permet d’obtenir les noms des élèves de la table eleves, classés par ordre
alphabétique.

Exemple 2:
Try {
      state.executeUpdate(“CREATE TABLE vendeur”+
                              “(NumVendeur integer”+
                              “, Nom char(15)”+
                              “, Prenom char(10)”+
                              “, DateEmbauche date”+
                              “, NumChef integer”+
                              “, Salaire numeric(6, 0)”+
                              “, Commission numeric(4, 1)”+
                              “, ContratID logical”+
                              “) ;”) ;
} catch (SQLException e){
...
    }

Ce traitement permet de créer une table vendeur dans la base de données courante.

Exemple 3:
Try {
      state.addBatch(“DELETE FROM vendeur WHERE numvendeur = ‘06897’”);
      state.addBatch(“UPDATE vendeur SET sal = 1215 WHERE sal < 1215”);
      int[] results = state.executeBatch();
} catch (SQLException e){
...
    }

Ce traitement permet de supprimer l’occurrence du vendeur ayant le numéro 06897 et de
fixer tous les salaires à 1215 minimum. Le tableau d’entiers results contiendra par exemple
[1, 15], ce qui signifie que la première requête aura affectée une seule ligne, tandis que la
seconde en aura affecté 15.

    7.2.    L’interface PreparedStatement : les requêtes précompilées

    L’objet PreparedStatement représente une instruction de traitement SQL précompilée.
C’est une sous interface de Statement. Cet objet est généralement utilisé lorsqu’il est
nécessaire de réutiliser plusieurs fois la même requête avec des paramètres différents,
identifiés par un « ? » dans la requête. Il est crée par l’intermédiaire d’une instance de
Connection par la méthode :

Public PreparedStatement prepareStatement(String sql) throws SQLException;

Exemple:
Try {
      PreparedStatement prepState = connect.prepareStatement(sql);
} catch (SQLException e){
...
    }

Cet objet est pourvu de méthodes permettant de:
                                                                                           9
A. Zribi, H. Maatallah, M. R. Haddad, A. Maatig

      •   Exécuter la requête SQL, retournant les résultats de celle-ci :
Public ResultSet executeQuery() throws SQLException ;
Public int executeUpdate() throws SQLException ;

      •   Spécifier le type et la valeur de tel ou tel argument :
Public void SETXxxx(int indiceParameter, Xxxx value) throws SQLException ;
Où Xxxx est le type de la valeur value
setString(int indiceParameter, String value);
setInt(int indiceParameter, Int value);

      •   Vider la liste des paramètres :
Public void clearParameters() throws SQLException ;

Exemple:
String sql = “SELECT nom FROM vendeur WHERE sexe = ? and niveau > ? ’’;
Try {
    PreparedStatement prepState = connect.prepareStatement(sql);
    prepState.setString(1, ‘‘F’’) ;
    prepState.setInt(2, 5) ;
    ResultSet rs = prepState.executeQuery();
    ...
    prepState.clearParameters() ;

       prepState.setString(1, ‘‘M’’) ;
       prepState.setInt(2, 3) ;
       rs = prepState.executeQuery();
       ...
}     catch (SQLException e){
...
      }

      Ceci permet d’obtenir les noms des vendeuses de niveau supérieur è 5, puis des
vendeurs de niveau supérieur à 3.

      7.3.    L’interface CallableStatement : les procédures stockées

     L’objet CallableStatement représente une instruction de traitement SQL stockée sur la
base de données. C’est une sous interface de PreparedStatement. Tout comme cette
dernière, il est possible de mettre des « ? » pour réutiliser la requête avec des paramètres
différents. Il est créé par l’intermédiaire d’une instance de Connection par la méthode :

Public CallableStatement prepareCall(String sql) throws SQLException;

      Exemple:

Try {
      CallableStatement callState = connect.prepareCall(sql);
} catch (SQLException e){
...
    }




                                                                                         10
A. Zribi, H. Maatallah, M. R. Haddad, A. Maatig

Il y a deux syntaxes possibles pour appeler une procédure procedure_name :

{call procedure_name[( ?, ?, …)]}

{? = call procedure_name[( ?, ?, …)]}

La seconde méthode permet d’avoir un paramètre de retour.

        Cet objet est pourvu de méthodes permettant de :

    •   Exécuter la requête SQL, retournant les résultats de celle-ci :
Public ResultSet executeQuery() throws SQLException ;
Public int executeUpdate() throws SQLException ;

    •   Spécifier le type et la valeur de tel ou tel argument :
Public void SETXxxx(int indiceParameter, Xxxx value) throws SQLException ;
Où Xxxx est le type de la valeur value
setString(int indiceParameter, String value);
setInt(int indiceParameter, Int value);

    •   Vider la liste des paramètres :
Public void clearParameters() throws SQLException ;


    •   Spécifier le type du paramètre renvoyé par la procédure stockée :
Public   void  registerOutParameter(int                numParam,    int   typeSQL)   throws
SQLException ;
Où numParam est le rang du paramètre et typeSQL est le type SQL du paramètre
(constantes disponibles dans java.sql.types).

    Exemple:

String sql = “{call liste_vendeur_par_ville(?)}” ;
Try {
      CallableStatement callState = connect.prepareCall(sql);
      callState.setString(1, “Paris”);
      ResultSet rs = callState.executeQuery();
      ...
} catch (SQLException e){
...
    }




                                                                                         11

								
To top