Centraliser les accès à la base de données
Bonjour à tous,
Je cherche le meilleur moyen de centraliser mes accès à une base de données. En gros, mon application possède un nombre important de classes (une vingtaine) qui font des requêtes directement à ma base de données.
Je compte changer tout cela de façon à ce qu'il n'y ait plus qu'un seul point d'accès vers ma base de données.
J'avais imaginé une solution, mais j'aimerais que vous me disiez si je suis sur la bonne voie, ou s'il y a de meilleures façons de faire (sans pour autant écrire quelque chose de trop complexe) :
Je crée une classe DatabaseAccess, qui est un singleton. Son rôle est d'initialiser les accès à la base de données. Cette classe serait donc la seule à avoir accès au pool de connections. Une fois cette initialisation réalisée, elle crée un Thread dont la tâche principale est d'exécuter la requête SQL. Ainsi, je peux réaliser plusieurs requêtes en parallèle, sans problème.
Du coup, si une classe désire faire une requête SQL, elle fait appel à mon singleton DatabaseAccess, qui se chargera de tout. Par exemple, j'imagine que je pourrais avoir quelque chose comme ça pour l'appel depuis cette classe :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
try {
String maRequete = "SELECT blabla...";
ResultSet monResultSet = null;
DatabaseAccess.getInstance().executeSelect(maRequete, monResultSet);
while (monResultSet == null) {
// Attente du resultat.
Thread.sleep(100);
}
// Code de traitement du resultset.
...
} catch (Exception e) {
// Si erreur lors de l'execution.
...
} |
C'est une idée comme ça, qui me parait à peu près propre et pas franchement complexe à coder. Qu'en pensez-vous ?
Merci pour votre aide.
Re: Centraliser les accès à la base de données
Salut,
Quelques remarques :
- Si le traitement doit être effectué dans un Thread, pourquoi attendre que ce thread soit terminé pour continuer ? --> Tu n'as pas besoin de faire le traitement dans un Thread séparé...
- La référence monResultSet que tu passes en paramètre à ta méthode ne sera jamais modifié dans la méthode appellante, et ta boucle d'attente sera infini...
- Je ne vois pas le code pour la libération des ressources (close() sur Connection/Statement/Resultset). Est-ce un oubli ?
- Tu traite toi-même ton ResultSet dans une boucle while(). Du coup en quoi est-ce différent d'une requête directe ? (il suffit de remplacer l'appel à executeSelect() par la création et l'exécution du Statement pour revenir au code précédent ou presque).
Perso je te conseilles l'API DbUtils de Jakarta, et donc de jeter un coup d'oeil au tutoriel de Christophe Jollivet : Simplifiez vous JDBC avec Jakarta Commons DbUtils, où alors d'attendre Java 6.0 qui intègrera un système similaire grâce aux annotations...
a++
Re: Centraliser les accès à la base de données
Citation:
Envoyé par adiGuba
Salut,
Quelques remarques :
- Si le traitement doit être effectué dans un Thread, pourquoi attendre que ce thread soit terminé pour continuer ? --> Tu n'as pas besoin de faire le traitement dans un Thread séparé...
- La référence monResultSet que tu passes en paramètre à ta méthode ne sera jamais modifié dans la méthode appellante, et ta boucle d'attente sera infini...
- Je ne vois pas le code pour la libération des ressources (close() sur Connection/Statement/Resultset). Est-ce un oubli ?
- Tu traite toi-même ton ResultSet dans une boucle while(). Du coup en quoi est-ce différent d'une requête directe ? (il suffit de remplacer l'appel à executeSelect() par la création et l'exécution du Statement pour revenir au code précédent ou presque).
Perso je te conseilles l'API DbUtils de Jakarta, et donc de jeter un coup d'oeil au tutoriel de
Christophe Jollivet : Simplifiez vous JDBC avec Jakarta Commons DbUtils, où alors d'attendre Java 6.0 qui intègrera un système similaire grâce aux annotations...
a++
Ha bah oui , y a aussi tout ca !! :wink:
Moi je parlais plus de conception sans trop regarder le code !!
Par contre on est d'accord sur le thread !!
Mais d'apres ce que j'ai compris sa conception est tout de meme meilleur que l'ancienne puisque il n'y auras plus qu'une seul classe gérant la connexion ou le pool de connexion ce qui semble plus facile a maintenir !!
Re: Centraliser les accès à la base de données
Merci pour tes réponses adiGuba. Quelques précisions donc :
1. Le traitement du résultat, je ne veux pas le faire dans un Thread. Le Thread n'aurait que pour rôle de récupérer le ResultSet (ou éventuellement de retourner un entier dans un cas d'un UPDATE, INSERT ou DELETE). Le traitement de ce ResultSet se ferait dans la classe qui appelle mon DatabaseAccess.
2. Concernant le code de libération des ressources, je ne l'ai pas écrit volontairement, pour ne pas surcharger le code là. Mais bien entendu, je ne comptais pas l'oublier, hein ;)
3. En fait, je voudrais juste qu'aucune classe - sauf DatabaseAccess et le Thread - n'accède directement à la base de données. Ces classes n'auraient donc en charge que l'initialisation de la requête et le traitement des résultats retournés.
Bon, je jette quand même un coup d'oeil sur DBUtils (que j'ai zappé trop rapidement hier en faisant mes recherches).
Merci.
Citation:
Envoyé par adiGuba
Salut,
Quelques remarques :
- Si le traitement doit être effectué dans un Thread, pourquoi attendre que ce thread soit terminé pour continuer ? --> Tu n'as pas besoin de faire le traitement dans un Thread séparé...
- La référence monResultSet que tu passes en paramètre à ta méthode ne sera jamais modifié dans la méthode appellante, et ta boucle d'attente sera infini...
- Je ne vois pas le code pour la libération des ressources (close() sur Connection/Statement/Resultset). Est-ce un oubli ?
- Tu traite toi-même ton ResultSet dans une boucle while(). Du coup en quoi est-ce différent d'une requête directe ? (il suffit de remplacer l'appel à executeSelect() par la création et l'exécution du Statement pour revenir au code précédent ou presque).
Perso je te conseilles l'API DbUtils de Jakarta, et donc de jeter un coup d'oeil au tutoriel de
Christophe Jollivet : Simplifiez vous JDBC avec Jakarta Commons DbUtils, où alors d'attendre Java 6.0 qui intègrera un système similaire grâce aux annotations...
a++
Re: Centraliser les accès à la base de données
Citation:
Envoyé par romaintaz
Merci pour tes réponses adiGuba. Quelques précisions donc :
1. Le traitement du résultat, je ne veux pas le faire dans un Thread. Le Thread n'aurait que pour rôle de récupérer le ResultSet
Mais pourquoi le faire dans un thread puisque de toute façon tu dois attendre le ResultSet en retour , les thread te permettent de paraleliser les tache et la en l'occurrence tu n'as jamais 2 taches en parallele puisque l'une attends le resultat de l'autre !
Re: Centraliser les accès à la base de données
Citation:
Envoyé par FreshVic
Mais pourquoi le faire dans un thread puisque de toute façon tu dois attendre le ResultSet en retour , les thread te permettent de paraleliser les tache et la en l'occurrence tu n'as jamais 2 taches en parallele puisque l'une attends le resultat de l'autre !
Prennons le cas de figure suivant :
La classe A et la classe B ont besoin d'accéder à la Base de Données.
- La classe A appelle DatabaseAccess.getInstance().executeSelect(...).
- Un Thread T1 est démarré par DatabaseAccess pour cette requête.
- Ma classe A attend alors le résultat du Thread T1.
Rien n'empêche que pendant ce temps, la classe B appelle à son tour DatabaseAccess.getInstance().executeSelect(...) pour une autre requête.
Un Thread T2 sera alors démarré pour cette requête, tandis que A attendra encore le résultat de T1.
Une fois T1 terminé, A aura les résultats de la requête, et pourra faire les traitements dessus...
Seule la classe A est bloquée par T1, et rien d'autre (je fais la supposition bien entendu que les classes A et B peuvent être exécutées en parallèle et ne dépendent pas l'une de l'autre).
Ou alors j'ai loupé quelque chose...
Re: Centraliser les accès à la base de données
Citation:
Envoyé par romaintaz
Rien n'empêche que pendant ce temps, la classe B appelle à son tour DatabaseAccess.getInstance().executeSelect(...) pour une autre requête.
Un Thread T2 sera alors démarré pour cette requête, tandis que A attendra encore le résultat de T1.
Une fois T1 terminé, A aura les résultats de la requête, et pourra faire les traitements dessus...
Si A et B sont deja dans 2 thread différent , ce que je pense etre le cas , puisque tu dis "pendant ce temps" tout le traitement que A demande au DataBaseAccess n'empecheras pas le thread executant B de faire appel à DatabaseAccess !
Mais j'ai peut etre rien compris :wink: