3. Connexion à la base

3.1. Établissement de la connexion

La connexion à la base consiste à demander au DriverManager un objet de type Connection, par l’appel de la méthode getConnection(). Là il n’y a qu’une seule façon de le faire : passer l’URL de la base, un nom de connexion et un mot de passe valides. L’appel de cette méthode renvoie un objet instance d’une classe qui implémente l’interface Connection.

Exemple 4. Obtenir une connexion du DriverManager

Connection con = DriverManager.getConnection(
 "jdbc:mysql::3306/db_test", 
 "user",  "passwd") ;

Si l'on a un objet de type DataSource à disposition, alors deux méthodes sont possibles. La première consiste à appeler simplement la méthode getConnection(), sans paramètre. Elle suppose que les identifiants de connexion ont été passés à la création de la DataSource, ce qui est en général le cas. Si ce n'est pas le cas, on peut appeler la méthode getConnection(user, passwd) afin d'obtenir une connexion. Examinons maintenant les propriétés de cet objet de type Connection.

3.2. Interface Connection

Comme nous l’avons déjà dit, Connection est une interface. L’objet que nous obtenons est donc une implémentation de cette interface par une classe que nous ne connaissons pas, et que nous n’avons pas besoin de connaître. Cette classe est propre à chaque serveur de base de données, et en général écrite par les développeurs de cette base de données. L’ouverture et la fermeture d’une connexion à une base de données sont deux choses qui doivent être traitées avec attention. L’ouverture est un processus coûteux. Sur certains serveurs, elle peut prendre plusieurs secondes. Une connexion ouverte sur une base de données est une ressource consommée. Comme toutes les ressources d’un système d’exploitation, elle est « rare », en tout cas, il existe un nombre maximal de connexions ouvertes à un instant donné. Cela rend indispensable la fermeture de toute connexion ouverte. Le fait que l'ouverture d'une connexion soit un processus coûteux est incontournable, aussi les serveurs d'applications JEE possèdent tous un mécanisme d'optimisation, qui consiste à ouvrir des connexions aux bases en avance, et à les stocker dans une réserve. Lorsqu'une demande de connexion arrive, elle peut être traitée immédiatement. Une fois que l'application n'a plus besoin de cette connexion, il la rend au gestionnaire de cette réserve. La gestion de cette réserve est à la charge du serveur d'application. Il existe des bibliothèques telles que DBCP (http://commons.apache.org/dbcp/) qui propose des implémentations de ce type, et qui peuvent être utilisées en contexte JSE. L’interface Connection comporte environ 45 méthodes, que l'on peut regrouper en trois catégories :
  • les méthodes de gestion de transaction ;
  • les méthodes de création de déclaration
  • les méthodes de gestion des objets.

3.2.1. Gestion des transactions

Par défaut, le mode de fonctionnement d'un pilote JDBC est auto-commit. Ce qui signifie qu'une demande de validation de transaction est passée à l'issue de chaque requête SQL passée. L'interface Connection propose deux méthodes :
  • getAutoCommit() : permet de tester dans quelle mode la connexion se trouve
  • setAutoCommit(boolean) : permet de changer ce mode.
Les autres méthodes qui permettent de gérer les transactions sont les suivantes :
  • commit(), rollback() : termine une transaction en validant ou annulant les modifications, respectivement.
  • setSavePoint() et setSavePoint(String) : permet de positionner un point de sauvegarde dans une transaction. Il est possible de donner un nom à ce point de sauvegarde. Ces deux méthodes renvoient un objet de type SavePoint, qui propose deux méthodes : getSavePointId() et getSavePointName().
  • releaseSavePoint(SavePoint) : permet de désactiver un point de sauvegarde.
  • rollBack(SavePoint) : annule les modifications dans cette transaction jusqu’au point de sauvegarde passé en paramètres.
La notions de save point dans une transaction n'est pas propre à JDBC, puisqu'elle existe également en SQL. Un point de sauvegarde peut être posé dans une transaction à tout moment. Il peut être alors utilisé pour annuler une partie de cette transaction, en appelant la méthode rollback(SavePoint). Enfin, on peut tester le niveau d’isolation de la transaction courante par appel de la méthode getTransactionIsolation(). Cette méthode renvoie une constante entière. Toutes les constantes possibles sont des variables statiques de la classe Connection. Distingons tout d’abord trois types de données :
  • les données dirty : ce sont des données qui sont actuellement modifiées dans une autre transaction, qui n’a été ni annulée ( rollback ), ni confirmée ( commit ).
  • les données phantom : objet susceptible d'apparaître lors d'une requête sur une plage de données.
  • les données non-repeatable : donnée modifiée dans une autre transaction qui a été validée.
Les constantes retournées par l’appel à la méthode getTransactionIsolation() sont les suivantes.

Tableau 4. Constantes retournées par getTransactionIsolation()

Constante Description
TRANSACTION_READ_UNCOMMITTED Deux select successifs sur un même objet peuvent retourner des valeurs différentes pour les champs de cet objet, s'il est en cours de modification dans une autre transaction ( dirty read ).
TRANSACTION_READ_COMMITED Deux select successifs sur un même objet peuvent retourner des valeurs différentes pour les champs de cet objet, s'il a été modifié dans une autre transaction validée ( non-repeatable read ).
TRANSACTION_REPEATABLE_READ Deux select successifs renvoient toujours le même résultat. En revanche les requêtes qui portent sur des plages de données sont susceptibles de faire apparaître de nouveaux éléments (objet phantom )
TRANSACTION_SERIALIZABLE L'isolation des transactions est totale, l'intégrité des données est entièrement respectée.
TRANSACTION_NONE La connexion est en mode non transactionnel.

3.2.2. Construction d'un Statement

Un objet de type Statement est un objet qui prend en charge une requête SQL, l’adresse au serveur et récupère un résultat. Le résultat est lui-même stocké dans un objet de type ResultSet. Un tel objet est obtenu par appel d’une des méthodes du type createStatement() de l’interface Connection.
Java Database Connectivity
Retour au blog Java le soir
Cours & Tutoriaux