2009-03-12 9 views
2

Je bientôt aller à partir de la phase de développement de mon cours et la conception actuelle est d'avoir une seule classe qui gère les connexions de base de données et de nombreuses classes qui appellent; la classe de base de données est censée ouvrir la connexion et passer les requêtes à l'aveugle, les autres classes sont responsables du contenu de ces requêtes.La meilleure façon pour de nombreuses classes de référencer une classe de connexion de base de données

Ce que je veux savoir quelle est la meilleure façon pour ces références à connaître la classe de base de données? Mon instinct serait de rendre les méthodes de la classe Database statiques et de les appeler Database.method() mais y a-t-il un meilleur moyen?

P.S. était référence le bon mot pour cela? Si ce n'est pas le bon mot, ça aiderait la prochaine fois que j'ai une question similaire.

Répondre

6

Soyez prudent.

Singleton sera un goulot d'étranglement.

java.sql.Connection est pas sûre, vous pouvez donc rencontrer des problèmes là-bas.

Je vous recommande d'écrire votre application avec des couches de service et de persistance complètement séparées. Les deux devraient être basés sur des interfaces. La couche de service est celle qui connaît les unités de travail et les transactions, en utilisant des objets de modèle et de persistance pour les remplir. Le service doit être responsable de l'acquisition de la connexion, de sa mise à disposition du niveau de persistance, de la gestion des transactions et de la fermeture de la connexion dans la même étendue de méthode que celle dans laquelle elle a été créée.

La portée et le nettoyage sont essentiels. Si vous ne le faites pas, vous épuiserez les connexions à la base de données.

Vous ne mentionnez pas les pools de connexion. Je recommanderais un.

Jetez un coup d'œil au printemps. Son module JDBC gère tout cela magnifiquement. Si vous ne pouvez pas utiliser Spring pour votre mission, au moins ce sera un bon modèle pour concevoir votre implémentation.

1

Évitez tout élément statique. Préférez "Parameterisation from Above".

donc ce que vous voulez faire est de créer votre objet wrapper de base de données à proximité de votre « principale ». Puis passez cela comme argument constructeur aux objets qui en ont besoin.

-1

Le Singleton pattern va vous aider pour cela. Voir more info à ce sujet ici.

Le motif (à juste titre) est détesté beaucoup ici, car il fait essentiellement un tas de méthodes globales, ce qui est à éviter dans le monde orienté objet - mais pour les cours et pour ce que vous essayez d'accomplir ça pourrait être plus facile.

+0

Je dirais qu'il faut éviter cela dans vos cours car c'est une mauvaise habitude à prendre. Il est beaucoup trop facile de laisser tomber un singleton dans "parce que c'est juste coursework/script simple/seulement utilisé ici" – tddmonkey

+1

J'utilise singletons aand monostates dans mon code et l'ai fait pendant les 20 dernières années sans effets secondaires. Ils sont juste un autre outil dans la boîte à outils des concepteurs. –

0

Si vous allez comme vous l'avez dit, vous allez avoir une unité de temps dure tester vos classes. Une façon de procéder peut être de transmettre vos informations de base de données aux classes qui effectuent la requête, par ex.

Query query = new GetPersonQuery(Database database); 
query.run(); // or whatever 

Cela fonctionne particulièrement bien si vous utilisez le modèle DAO, donc:

PersonDao dao = new PersonDao(Database database); 
dao.findAll(); 

La base de données peut alors envelopper tout ce que vous avez besoin, par exemple Mise en pool des connexions, mise en cache, etc.

0

Si vous souhaitez stocker la connexion de manière statique, utilisez au moins un thread local.Mais comme d'autres l'ont dit ici - mieux d'injecter la connexion, ou son emballage, dans les objets qui ont besoin de l'utiliser.

4

L'approche traditionnelle consiste à avoir un objet DAO (Data Access Object) pour chaque classe de données.

I.e. Si vous avez une classe de données "Person", vous avez aussi une classe "PersonDAO" qui implémente des méthodes comme findById(), findAll(), save (Person), etc. La classe DAO gère la totalité de l'interaction DB.

Le constructeur de la classe DAO pouvait simplement accepter un objet Connection et ainsi externaliser le problème de la création de connexions ou il pouvait invoquer une méthode usine quelque part qui distribuait un objet Connection.

Dans les deux cas, vous aurez probablement besoin d'une telle méthode d'usine.

public class Database{ 
    public static Connection getConnection(){ 
     // Create a new connection or use some connection pooling library 
    } 
} 

Comme quelqu'un a fait remarquer java.sql.Connection est pas sûre que vous ne devriez pas remettre la même connexion à chaque fois, sauf si vous êtes sûr que plusieurs threads ne seront pas accédaient la méthode.

Bien sûr, si vous devez créer une nouvelle connexion pour chaque appel, vous devrez également fermer les connexions une fois que vous avez terminé. L'approche simple consiste à ajouter une méthode close() aux DAO et à les faire prendre en charge. Cela impose une charge sur le code en utilisant le DAO.

Même si vous utilisez le regroupement de connexions, il est toujours nécessaire de fermer les connexions (retour au pool) une fois que vous avez terminé.

Quelqu'un a suggéré d'utiliser Thread local pour avoir une connexion par thread. Cela fonctionne dans certains cas, mais ne serait pas utile pour une application web où chaque requête est un nouveau thread (qui n'est jamais réutilisé, pourrait aussi bien ne pas stocker une référence). Vous pouvez cependant en profiter dans une application Web si vous l'avez configurée de sorte qu'après avoir traité chaque requête, un appel soit fait à Database.closeConnection() qui prend alors soin de fermer une connexion locale Tread s'il en existe une.

Questions connexes