Bienvenue dans le tutoriel sur l’exemple de la mise en cache de premier niveau avec Hibernate. Récemment, nous avons examiné l’architecture Hibernate, le mappage Hibernate et comment utiliser HQL pour exécuter des requêtes SQL de manière orientée objet. Aujourd’hui, nous allons nous pencher sur l’un des aspects importants de Hibernate – la mise en cache Hibernate.
La mise en cache Hibernate
La mise en cache Hibernate peut être très utile pour améliorer les performances de l’application si elle est utilisée correctement. L’idée derrière la mise en cache est de réduire le nombre de requêtes à la base de données, réduisant ainsi le temps de traitement de l’application. Hibernate propose différents types de caches :
- Cache de Premier Niveau: Le cache de premier niveau de Hibernate est associé à l’objet Session. Le cache de premier niveau de Hibernate est activé par défaut et il n’y a aucun moyen de le désactiver. Cependant, Hibernate fournit des méthodes grâce auxquelles nous pouvons supprimer des objets sélectionnés du cache ou vider complètement le cache. Tout objet mis en cache dans une session ne sera pas visible pour d’autres sessions, et lorsque la session est fermée, tous les objets mis en cache seront également perdus.
- Cache de Second Niveau: Le cache de second niveau de Hibernate est désactivé par défaut, mais nous pouvons l’activer via la configuration. Actuellement, EHCache et Infinispan fournissent une implémentation pour le cache de second niveau de Hibernate, et nous pouvons les utiliser. Nous examinerons cela dans le prochain tutoriel sur le caching de Hibernate.
- Cache de Requête: Hibernate peut également mettre en cache le jeu de résultats d’une requête. Le cache de requête de Hibernate ne met pas en cache l’état réel des entités dans le cache; il met en cache uniquement les valeurs d’identifiant et les résultats de type de valeur. Il doit donc toujours être utilisé en conjonction avec le cache de second niveau.
Exemple de Cache Hibernate – Cache de Premier Niveau
Pour mon programme d’exemple de cache de premier niveau Hibernate, j’utilise la même configuration que dans l’Exemple HQL, vous pouvez vérifier cela et configurer les tables en les peuplant avec des données factices. Regardons d’abord le programme, sa sortie, puis nous examinerons certains points importants liés au cache de premier niveau Hibernate. HibernateCacheExample.java
package com.journaldev.hibernate.main;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import com.journaldev.hibernate.model.Employee;
import com.journaldev.hibernate.util.HibernateUtil;
public class HibernateCacheExample {
public static void main(String[] args) throws InterruptedException {
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
Session session = sessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();
//Obtenez l'employé avec l'id=1
Employee emp = (Employee) session.load(Employee.class, new Long(1));
printData(emp,1);
//Attendez un moment pour changer les données en arrière-plan
Thread.sleep(10000);
//Récupérez à nouveau les mêmes données, vérifiez les journaux qu'aucune requête n'a été exécutée
Employee emp1 = (Employee) session.load(Employee.class, new Long(1));
printData(emp1,2);
//Créez une nouvelle session
Session newSession = sessionFactory.openSession();
//Obtenez l'employé avec l'id=1, notice the logs for query
Employee emp2 = (Employee) newSession.load(Employee.class, new Long(1));
printData(emp2,3);
//DÉBUT : exemple d'éviction pour supprimer un objet spécifique du cache de premier niveau Hibernate
//Obtenez l'employé avec l'id=2, première fois donc requête dans les journaux
Employee emp3 = (Employee) session.load(Employee.class, new Long(2));
printData(emp3,4);
//éviction de l'objet employé avec l'id=1
session.evict(emp);
System.out.println("Session Contains Employee with id=1?"+session.contains(emp));
//puisque l'objet est supprimé du cache de premier niveau, vous verrez une requête dans les journaux
Employee emp4 = (Employee) session.load(Employee.class, new Long(1));
printData(emp4,5);
//cet objet est toujours présent, donc vous ne verrez pas de requête dans les journaux
Employee emp5 = (Employee) session.load(Employee.class, new Long(2));
printData(emp5,6);
//FIN : exemple d'éviction
//DÉBUT : exemple de suppression pour tout supprimer du cache de premier niveau
session.clear();
Employee emp6 = (Employee) session.load(Employee.class, new Long(1));
printData(emp6,7);
Employee emp7 = (Employee) session.load(Employee.class, new Long(2));
printData(emp7,8);
System.out.println("Session Contains Employee with id=2?"+session.contains(emp7));
tx.commit();
sessionFactory.close();
}
private static void printData(Employee emp, int count) {
System.out.println(count+":: Name="+emp.getName()+", Zipcode="+emp.getAddress().getZipcode());
}
}
Lorsque nous exécutons l’exemple ci-dessus, la sortie contient beaucoup d’informations liées à Hibernate. Mais nous sommes principalement intéressés par la sortie spécifique à notre code et les requêtes exécutées par Hibernate pour charger les données. L’extrait de sortie ressemble à ce qui suit.
Hibernate Configuration loaded
Hibernate serviceRegistry created
Hibernate: select employee0_.emp_id as emp_id1_1_0_, employee0_.emp_name as emp_name2_1_0_, employee0_.emp_salary as emp_sala3_1_0_, address1_.emp_id as emp_id1_0_1_, address1_.address_line1 as address_2_0_1_, address1_.city as city3_0_1_, address1_.zipcode as zipcode4_0_1_ from EMPLOYEE employee0_ left outer join ADDRESS address1_ on employee0_.emp_id=address1_.emp_id where employee0_.emp_id=?
1:: Name=Pankaj, Zipcode=95129
2:: Name=Pankaj, Zipcode=95129
Hibernate: select employee0_.emp_id as emp_id1_1_0_, employee0_.emp_name as emp_name2_1_0_, employee0_.emp_salary as emp_sala3_1_0_, address1_.emp_id as emp_id1_0_1_, address1_.address_line1 as address_2_0_1_, address1_.city as city3_0_1_, address1_.zipcode as zipcode4_0_1_ from EMPLOYEE employee0_ left outer join ADDRESS address1_ on employee0_.emp_id=address1_.emp_id where employee0_.emp_id=?
3:: Name=PankajK, Zipcode=95129
Hibernate: select employee0_.emp_id as emp_id1_1_0_, employee0_.emp_name as emp_name2_1_0_, employee0_.emp_salary as emp_sala3_1_0_, address1_.emp_id as emp_id1_0_1_, address1_.address_line1 as address_2_0_1_, address1_.city as city3_0_1_, address1_.zipcode as zipcode4_0_1_ from EMPLOYEE employee0_ left outer join ADDRESS address1_ on employee0_.emp_id=address1_.emp_id where employee0_.emp_id=?
4:: Name=David, Zipcode=95051
Session Contains Employee with id=1?false
Hibernate: select employee0_.emp_id as emp_id1_1_0_, employee0_.emp_name as emp_name2_1_0_, employee0_.emp_salary as emp_sala3_1_0_, address1_.emp_id as emp_id1_0_1_, address1_.address_line1 as address_2_0_1_, address1_.city as city3_0_1_, address1_.zipcode as zipcode4_0_1_ from EMPLOYEE employee0_ left outer join ADDRESS address1_ on employee0_.emp_id=address1_.emp_id where employee0_.emp_id=?
5:: Name=Pankaj, Zipcode=95129
6:: Name=David, Zipcode=95051
Hibernate: select employee0_.emp_id as emp_id1_1_0_, employee0_.emp_name as emp_name2_1_0_, employee0_.emp_salary as emp_sala3_1_0_, address1_.emp_id as emp_id1_0_1_, address1_.address_line1 as address_2_0_1_, address1_.city as city3_0_1_, address1_.zipcode as zipcode4_0_1_ from EMPLOYEE employee0_ left outer join ADDRESS address1_ on employee0_.emp_id=address1_.emp_id where employee0_.emp_id=?
7:: Name=Pankaj, Zipcode=95129
Hibernate: select employee0_.emp_id as emp_id1_1_0_, employee0_.emp_name as emp_name2_1_0_, employee0_.emp_salary as emp_sala3_1_0_, address1_.emp_id as emp_id1_0_1_, address1_.address_line1 as address_2_0_1_, address1_.city as city3_0_1_, address1_.zipcode as zipcode4_0_1_ from EMPLOYEE employee0_ left outer join ADDRESS address1_ on employee0_.emp_id=address1_.emp_id where employee0_.emp_id=?
8:: Name=David, Zipcode=95051
Session Contains Employee with id=2?true
Cache de premier niveau dans Hibernate Points importants
Points importants sur le cache de premier niveau dans Hibernate qui peuvent être déduits du programme ci-dessus sont:
- Le cache de premier niveau d’Hibernate est activé par défaut, aucune configuration n’est nécessaire pour cela.
- Le cache de premier niveau d’Hibernate est spécifique à la session, c’est pourquoi lorsque nous obtenons les mêmes données dans la même session, aucune requête n’est exécutée, alors que dans une autre session, une requête est exécutée pour charger les données.
- Le cache de premier niveau d’Hibernate peut contenir d’anciennes valeurs, comme on peut le voir ci-dessus, j’ai mis mon programme en veille pendant 10 secondes et pendant ce temps, j’ai mis à jour la valeur (nom de Pankaj à PankajK) dans la base de données, mais cela n’a pas été reflété dans la même session. Mais dans une autre session, nous avons obtenu la valeur mise à jour.
- Nous pouvons utiliser la méthode
evict()
de la session pour supprimer un seul objet du cache de premier niveau d’Hibernate. - Nous pouvons utiliser la méthode
clear()
de la session pour effacer le cache, c’est-à-dire supprimer tous les objets du cache. - Nous pouvons utiliser la méthode
contains()
de la session pour vérifier si un objet est présent dans le cache Hibernate ou non, si l’objet est trouvé dans le cache, elle renvoie true, sinon elle renvoie false. - Étant donné qu’Hibernate met en cache tous les objets dans le cache de premier niveau de la session, lors de l’exécution de requêtes en vrac ou de mises à jour par lots, il est nécessaire de vider le cache à certains intervalles pour éviter les problèmes de mémoire.
C’est tout pour la mise en cache Hibernate et l’exemple de cache de premier niveau, dans les futurs articles, nous examinerons l’implémentation du Cache de Deuxième Niveau Hibernate – EHCache.
Source:
https://www.digitalocean.com/community/tutorials/hibernate-caching-first-level-cache