Simplifiez vous JDBC avec Jakarta Commons DbUtilsDate de publication : 10/12/04 , Date de mise à jour : 10/12/04
Par
Christophe Jollivet (mes autres tutoriels) Au cours de ce tutoriel vous allez apprendre comment l'API Jakarta Commons DbUtils peut vous simplifier l'utilisation de JDBC par l'ajout d'une couche d'abstraction supplémentaire Merci 1. Introduction 2. L'API 2.1. DbUtils 2.2. ResultSetHandler 2.3. QueryLoader 2.4. QueryRunner 3. Un peu de pratique 3.1. Structure de la base de données 3.2. Le code 3.2.1. La classe de test 3.2.2. Le Bean 3.2.3. Le fichier queries.properties 3.2.4. Explications 4. Conclusion Merci
Merci à Stessy pour les corrections et les suggestions, ainsi qu'à Bestiol pour le deuxième tour de corrections.
1. Introduction
L'écriture d'un bon code JDBC n'est pas très difficile.
Mais cette tâche peut vite devenir répétitive et pénible.
De plus les erreurs sont souvent difficiles à retrouver. L'API DbUtils de Jakarta Commons est simple et facile d'usage. Elle ne fait pas grand chose de compliqué mais simplifie beaucoup la tâche du développeur en encapsulant l'usage de JDBC. Bien qu'il existe de nombreux frameworks de persistance qui rendent la gestion de JDBC transparente, leur mise en place et configuration plutôt complexes font souvent qu'ils ne sont pas utilisés sur des projets de plus faible envergure. L'objectif de DbUtils n'est pas le remplacement des frameworks de persistance, mais la simplification de l'utilisation de JDBC. La gestion de la persistance des objets reste la tâche du programmeur. DbUtils est disponible en téléchargement à l'adresse suivante : http://jakarta.apache.org/commons/dbutils/Cette API ne dépend d'aucune autre API de Jakarta Commons et ne nécessite qu'un JDK version 1.2 ou plus et JDBC 2.0 ou plus. La documentation n'est pas la plus fournie, mais reste néanmoins suffisante une fois que l'on a compris le principe. L'objectif de ce tutoriel est de présenter sommairement cette API ainsi que ses avantages au travers d'un rapide descriptif et d'exemples.
Si vous voulez savoir ce que cette API peut vous apporter, comparez les deux fonctions ci dessous.
Toutes les deux effectuent une connexion avec une base de données MySQL à partir d'un objet DataSource reçu en paramètre et renvoie une List de Bean du type EleveBean.
Ce bean conprend trois attributs : nom, age et classe.
2. L'API
L'API est constituée de 3 packages:
Dans ce tutoriel nous allons voir trois classes (org.apache.commons.dbutils.DbUtils, org.apache.commons.dbutils.QueryRunner et org.apache.commons.dbutils.QueryLoader) et une interface (org.apache.commons.dbutils.ResultSetHandler).
Puis nous verrons un exemple d'utilisation.
2.1. DbUtils
Toutes les méthodes de cette classe sont statiques.
Ce sont des méthodes utilitaires qui permettent de faire toutes les tâches de routines s'articulant autour de l'utilisation d'une base de données (chargement de driver JDBC, ouverture et fermeture de connexions).
Nous allons voir quelques unes de ces méthodes :
2.2. ResultSetHandler
L'implémentation de cette interface par une classe lui permet de manipuler des ResultSet et convertir les données qu'ils contiennent dans une autre forme.
L'API fournit huit implémentations de cette interface permettant d'obtenir au choix : un tableau, un Bean, un Map, un List des précédents objets ou une gestion du ResultSet par colonne (une colonne dans un objet ou un List d'objets correspondant aux colonnes). L'interface présente une seule méthode : Object handle(java.sql.ResultSet rs). Ainsi toutes les implémentations de ResultSetHandler acceptent en paramètre un ResultSet et renvoient un java.lang.Object. Par conséquent, exception faite des types primitifs, il n'y a pas de restriction sur ce qui peut être retourné par votre implémentation de l'interface. 2.3. QueryLoader
Cette classe permet le chargement d'une Map contenant les différentes requêtes SQL à partir d'un fichier properties.
Cette externalisation de vos requêtes permet d'en faciliter des éventuelles optimisations.
Cette Map ne doit pas être demandée par un chemin de fichier système mais comme une ressource du jar de l'application.
Cette classe est un singleton qui s'utilise comme un registre pour vos requêtes.
Les deux méthodes intéressantes de cette classe sont :
2.4. QueryRunner
Cette classe simplifie l'exécution de la requête.
En association avec un ResultSetHandler, elle permet de réduire considérablement le code nécessaire.
Cette classe dispose de deux constructeurs.
Le premier est un constructeur sans argument, le second prend un javax.sql.DataSource en paramètre.
Si vous ne fournissez pas de Connection comme argument à une méthode, le DataSource fourni au constructeur est utilisé pour l'obtention d'une nouvelle connexion.
Le DataSource peut aussi être paramétré avec la méthode setDataSource(). Les méthodes importantes de cette classe sont :
3. Un peu de pratique
Pour la mise en pratique, nous allons réaliser une application en mode console, avec une base de données MySQL. 4.0.15, un pilote JDBC : mysql-connector-java-3.0.15. Dans ce programme, nous allons effectuer 3 tests de récupération de données :
Les requêtes des deuxième et troisième tests seront dans un fichier properties.
3.1. Structure de la base de données
Sur la base de données MySQL, le tutoriel utilise une base appelée " base " avec un user " user " et un password " password ".
La base contient une table " eleve " avec trois champs
3.2. Le code3.2.1. La classe de test
3.2.2. Le Bean
Ce Bean est destiné à recevoir les informations de la base de données.
3.2.3. Le fichier queries.properties
Il s'agit d'un simple fichier texte. Il contient deux requêtes.
La première est une requête simple, la seconde accepte un paramètre.
3.2.4. Explications
Dans ce programme de test, nous commençons par utiliser la classe DbUtils pour établir la connexion à la base de données.
Cette connexion sera ensuite passée en paramètre pour l'exécution des requêtes.
Nous créons aussi une instance de QueryRunner pour l'exécution des requêtes.
Je rappelle que si vous travaillez avec un pool de connexions, il est possible de passer directement le DataSource en paramètre lors de la construction de QueryRunner.
L'utilisation de DbUtils n'est alors plus nécessaire.
Pour le premier test, nous commençons par une requête simple de toute la base avec un ArrayListHandler.
Elle renvoie une ArrayList (list1)dont chaque élément est un tableau d'Object (données[]) qui correspondent chacun à un tuple.
Chaque Object du tableau est une donnée de la base.
Dans notre exemple, le cast de ces Object n'est pas nécessaire pour l'affichage, mais il peut le devenir selon votre utilisation.
Au début du second test, nous chargeons la Map avec les requêtes.
Nous effectuons alors une requête avec un paramètre et utilisons un Arrayhandler, le paramètre étant la clé primaire de la table, la réponse est constituée d'un tuple maximum.
Ce tuple nous est retourné sous la forme d'un tableau d'Object.
Ce tableau d'Object est ensuite affiché.
Pour le troisième test, nous utilisons encore une requête de la Map, mais avec un Bean pour recevoir le résultat.
L'utilisation du BeanListHandler simplifie beaucoup celle d'une base de données puisque la commande nous renvoie directement une ArrayList de Bean correspondant chacun à un tuple de la base de données.
L'utilisation du BeanListHandler amène toutefois quelques contraintes.
En effet, il faut que les noms et types de colonnes de votre ResultSet correspondent aux différents champs de votre Bean.
Pour cela, il est possible d'utiliser des alias pour les titres de vos colonnes dans votre requête du genre : "Select colonne1 as value1, colonne2 as value2 from table".
Vous n'êtes pas obligé d'aller chercher la valeur de tous les attributs de votre Bean dans la base de données.
Pour finir la fin du programme de test ferme la connexion à la base de données de façon silencieuse, c'est à dire en empêchant une éventuelle Exception de remonter.
4. Conclusion
Dans ce tutoriel, nous avons vu que l'utilisation de l'API jakarta.commons.DbUtils permet de se simplifier beaucoup l'accès à une base de données.
En effet il est possible d'externaliser vos requêtes vers un fichier properties pour en faciliter la modification.
Il est aussi possible d'éviter l'écriture de bloc try-catch en faisant passer sous silence certaines exceptions sans incidence (lors de la fermeture de la connexion).
Enfin lors de l'utilisation avec un pool de connexions, il est possible d'obtenir une ArrayList de Bean à partir de la base de données avec seulement deux instructions.
|
Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2004 Christophe Jollivet. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts. Cette page est déposée.
Copyright © 2000-2012 - www.developpez.com