Contenu du cours
Manipulation des Données Java avec Hibernate
Manipulation des Données Java avec Hibernate
Implémentation du Modèle DAO pour Notre Programme
Toute théorie doit être renforcée par la pratique. Dans le chapitre précédent, nous avons appris le flux de travail de Hibernate, ses cycles de vie, et examiné le code de base qui est utilisé presque toujours. Dans ce chapitre, je propose de commencer à mettre en œuvre l'interaction entre la base de données et le code, au moins avec les deux classes d'entités que nous avons actuellement. Nous utiliserons le modèle DAO, ce qui signifie que la logique d'interaction avec la base de données sera séparée de la logique métier de l'application.
HibernateUtil
Comme vous vous en souvenez peut-être du chapitre précédent, créer un objet SessionFactory
consomme beaucoup de ressources. Par conséquent, nous devons optimiser le code pour que cet objet soit créé une seule fois pendant l'exécution du programme. Nous le ferons dans le fichier HibernateUtil.java
.
Nous devons nous assurer qu'une instance de l'objet SessionFactory
est créée et stockée dans une constante statique, et non modifiée par d'autres fichiers. Pour ce faire, nous créerons une méthode privée, initSessionFactory()
, dans cette classe, qui configurera et construira l'objet SessionFactory
. Ensuite, attribuez cet objet à l'instance. De plus, il devrait y avoir un getter statique public afin que nous n'accédions à cet objet que par son intermédiaire.
En fin de compte, cette classe ressemblera à ceci :
De cette façon, l'objet SessionFactory
sera créé une seule fois, et nous l'utiliserons pour créer différentes sessions pour manipuler les objets. Plus tard, nous verrons comment utiliser correctement cet utilitaire.
Remarque
De tels utilitaires sont souvent utilisés en programmation pour faciliter l'écriture de code et optimiser les ressources. Nous, en tant que futurs programmeurs, les utiliserons également. C'est une très bonne pratique.
Couche DAO
Commençons par implémenter la couche DAO. Juste un rappel, c'est la couche où le code interagit avec la base de données, récupérant et stockant des données. Ici, nous devrions diviser le code en une interface et une classe d'implémentation. L'interface servira de modèle, définissant toutes les méthodes que nous devons implémenter. La classe d'implémentation les implémentera.
Commençons par l'entité Employee
:
Comme vous pouvez le voir, nous prévoyons d'implémenter seulement 2 méthodes pour l'instant : getById()
et add()
. Plus tard, lorsque nous aurons besoin d'autres méthodes pour le programme, nous pourrons facilement étendre ce code en ajoutant de nouvelles méthodes à cette interface.
Ensuite, nous devons implémenter l'implémentation. Elle sera située dans la classe EmployeeDaoImpl
.
Maintenant, nous devons appliquer la théorie du chapitre précédent et l'utiliser pour implémenter ces 2 méthodes.
Tout d'abord, nous devons créer et utiliser une instance de l'objet SessionFactory
. Nous le ferons en utilisant l'utilitaire HibernateUtil
que nous avons implémenté auparavant :
Super, maintenant, avec ce sessionFactory
, nous pourrons ouvrir des sessions dans cette classe.
Remarque
Notez que la variable est
private
, ce qui signifie qu'elle ne peut être utilisée que dans cette classe. De plus, cette variable n'est pas un nouveauSessionFactory
; c'est une instance deSessionFactory
créée dans la classeHibernateUtil
.
Commençons à implémenter la méthode add()
.
Nous suivrons le modèle du chapitre précédent :
Initialement, dans la méthode, nous créons les variables session
et transaction
, en les initialisant à null. Cela est fait pour mieux suivre l'état de ces variables, en cas de problème, pour fermer la session
ou annuler la transaction
.
Ensuite, nous suivons l'algorithme familier :
Dans le bloc catch
, nous attrapons les erreurs potentielles, et si la transaction
a été modifiée, nous l'annulons. De plus, nous lançons une nouvelle exception, indiquant que nous ne pouvons pas ajouter un nouvel employé.
Dans le bloc finally
, nous vérifions également si l'objet session
a été modifié, puis nous fermons la session
dans laquelle nous travaillons.
Passons maintenant à l'implémentation de la méthode getById
, qui prend un id en paramètre et retourne un élément de la base de données :
Ici, l'algorithme est également similaire et simple. La différence est que nous ne créons pas d'objet transaction
.
Remarque
Une transaction est utilisée lorsque nos modifications affectent l'état de la table dans la base de données. La plupart des requêtes du groupe READ n'affectent pas la base de données, donc nous n'utilisons pas d'objet
transaction
lors de l'implémentation de cette méthode.
Ensuite, voici l'algorithme familier. En cas de capture d'une exception, nous lançons une nouvelle exception pour notifier l'utilisateur que nous n'avons pas réussi à récupérer un employé par ID. Dans le bloc finally
, nous fermons la session en cours.
Remarque
Notez que nous utilisons la même instance
sessionFactory
créée dans ce fichier. Nous ne créons pas une nouvelle instance pour chaque méthode.
Couche de Service
Nous avons séparé l'interaction du code avec la base de données en une couche distincte. Il est temps d'écrire la couche de service, qui contiendra toute la logique métier de l'application. Pour le moment, notre application est très simple car nous sommes en train d'apprendre. Par conséquent, la couche de service devrait imiter les méthodes de la couche DAO. Plus tard, à mesure que l'application se développe et que la logique devient plus complexe, nous améliorerons la couche de service.
La couche de service devrait également avoir la structure Interface - Implémentation.
Implémentons l'interface EmployeeService
:
Je ne pense pas qu'il y ait beaucoup à commenter ici ; nous avons simplement répliqué les méthodes de la couche DAO dans ce code. Pour l'instant, ce sont les méthodes dont nous avons besoin.
Écrivons maintenant l'implémentation :
Nous utilisons l'instance de l'objet EmployeeDao
par composition.
- Dans la méthode
add()
, nous utilisons simplement une méthode de la couche DAO ; - Dans la méthode
getById()
, nous vérifions si nous avons réussi à récupérer un employé par ID, et si c'est le cas, nous retournons cet objet. Sinon, nous lançons uneNoSuchElementException
, indiquant que nous n'avons pas pu récupérer un employé par ID.
Pour le moment, l'implémentation de la couche de service semble simple, mais ajoutons un peu de logique supplémentaire à l'application. Par exemple, une méthode qui récupère le nom d'un employé par son ID. Nous devrions implémenter cette méthode dans la couche de service car c'est de la logique métier et ne devrait pas affecter directement l'interaction avec la base de données.
Pour commencer, ajoutons la méthode à l'interface :
Implémentons maintenant cette méthode :
- Tout d'abord, nous récupérons l'
Employee
en tant qu'objet en utilisant la méthodegetById
précédemment implémentée ; - Ensuite, nous créons une variable pour stocker le nom de l'employé, en récupérant le nom à l'aide d'un getter ;
- Vérification standard de null et retourner le nom de l'employé depuis la méthode.
Il est très important d'ajouter une logique supplémentaire, spécifiquement au niveau du service. Oui, nous pourrions impliquer la couche DAO, mais pourquoi ajouter une interaction supplémentaire avec la base de données si nous pouvons l'éviter ?
Tester la Correction des Méthodes.
Maintenant que tout est en place, nous pouvons enfin utiliser ces méthodes.
Nous le ferons selon l'algorithme suivant :
- Instancier le
EmployeeService
; - Créer un nouvel objet
employee
et initialiser ses champs à l'aide des setters ; - Ajouter l'
employee
à la base de données ; - Récupérer l'
employee
par ID et l'imprimer sur la console ; - Récupérer le nom de l'employé par ID et l'imprimer sur la console.
Jetons un coup d'œil à l'implémentation dans le code :
Comme vous pouvez le voir, c'est assez simple. Ensuite, tout ce que nous devons faire est d'exécuter ce code et ainsi vérifier son bon fonctionnement.
Super, nous avons entièrement implémenté la connexion à la base de données pour l'une de nos entités. Dans le prochain chapitre, vous allez implémenter indépendamment la même connexion pour l'entité Department
. Ce sera un excellent exercice !
1. Quel est le but de la classe HibernateUtil
dans un projet Hibernate ?
2. Dans le modèle DAO, quel est le rôle principal de l'interface DAO ?
3. Comment la couche service interagit-elle avec la couche DAO dans l'implémentation donnée ?
Merci pour vos commentaires !