Hibernate Caching – First Level Cache Beispiel-Tutorial
In diesem Tutorial erkunden wir den leistungsstarken Hibernate-Caching-Mechanismus, mit Schwerpunkt auf dem First Level Cache. Lernen Sie, wie Hibernate Datenbankinteraktionen optimiert, Abfragezeiten reduziert und die Anwendungsleistung verbessert. Wir tauchen in praktische Beispiele ein, untersuchen wichtige Konzepte und heben wichtige Punkte hervor, um Ihnen zu helfen, das Beste aus Hibernate-Caching in Ihren Projekten herauszuholen.
Hibernate Caching
Hibernate Cache kann sehr nützlich sein, um eine schnelle Anwendungsleistung zu erzielen, wenn er richtig eingesetzt wird. Die Idee hinter dem Cache ist es, die Anzahl der Datenbankabfragen zu reduzieren, wodurch die Durchlaufzeit der Anwendung verringert wird. Hibernate bietet verschiedene Arten von Caches:
First Level Cache
Der First Level Cache von Hibernate ist mit dem Session-Objekt verknüpft. Er ist standardmäßig aktiviert und es gibt keine Möglichkeit, ihn zu deaktivieren. Hibernate stellt jedoch Methoden zur Verfügung, mit denen wir ausgewählte Objekte aus dem Cache löschen oder den Cache vollständig leeren können. Jedes in einer Sitzung zwischengespeicherte Objekt ist für andere Sitzungen nicht sichtbar, und wenn die Sitzung geschlossen wird, gehen alle zwischengespeicherten Objekte ebenfalls verloren.
Second Level Cache
Der Second Level Cache von Hibernate ist standardmäßig deaktiviert, kann jedoch durch Konfiguration aktiviert werden. Derzeit bieten EHCache und Infinispan Implementierungen für den Second Level Cache von Hibernate an, die wir verwenden können. Wir werden dies im nächsten Tutorial zum Hibernate-Caching behandeln.
Query Cache
Hibernate kann auch das Ergebnis einer Abfrage zwischenspeichern. Der Query Cache von Hibernate speichert nicht den Zustand der tatsächlichen Entitäten im Cache, sondern nur die Identifizierungswerte und Ergebnisse von Werttypen. Daher sollte er immer in Verbindung mit dem Second Level Cache verwendet werden.
Hibernate Caching – First Level Cache Beispiel
Für mein Beispielprogramm zum First Level Cache von Hibernate verwende ich dieselbe Konfiguration wie im HQL-Beispiel. Sie können dies überprüfen und die Tabellen konfigurieren sowie mit Beispieldaten füllen. Schauen wir uns zunächst das Programm, dessen Ausgabe und einige wichtige Punkte zum First Level Cache von Hibernate an.
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();
//Get employee with id=1
Employee emp = (Employee) session.load(Employee.class, new Long(1));
printData(emp,1);
//waiting for sometime to change the data in backend
Thread.sleep(10000);
//Fetch same data again, check logs that no query fired
Employee emp1 = (Employee) session.load(Employee.class, new Long(1));
printData(emp1,2);
//Create new session
Session newSession = sessionFactory.openSession();
//Get employee with id=1, notice the logs for query
Employee emp2 = (Employee) newSession.load(Employee.class, new Long(1));
printData(emp2,3);
//START: evict example to remove specific object from hibernate first level cache
//Get employee with id=2, first time hence query in logs
Employee emp3 = (Employee) session.load(Employee.class, new Long(2));
printData(emp3,4);
//evict the employee object with id=1
session.evict(emp);
System.out.println("Session Contains Employee with id=1?"+session.contains(emp));
//since object is removed from first level cache, you will see query in logs
Employee emp4 = (Employee) session.load(Employee.class, new Long(1));
printData(emp4,5);
//this object is still present, so you won't see query in logs
Employee emp5 = (Employee) session.load(Employee.class, new Long(2));
printData(emp5,6);
//END: evict example
//START: clear example to remove everything from first level cache
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());
}
}
Wenn wir das obige Beispiel ausführen, enthält die Ausgabe viele hibernate-bezogene Informationen. Wir sind jedoch hauptsächlich an unserer codespezifischen Ausgabe und den von Hibernate ausgelösten Abfragen interessiert. Der Ausgabeschnipsel sieht wie folgt aus:
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
Wichtige Punkte zum First Level Cache in Hibernate
Wichtige Punkte zum First Level Cache in Hibernate, die aus dem obigen Programm abgeleitet werden können:
- Der First Level Cache von Hibernate ist standardmäßig aktiviert, es sind keine Konfigurationen erforderlich.
- Der First Level Cache von Hibernate ist sitzungsspezifisch. Deshalb wird beim Abrufen derselben Daten in derselben Sitzung keine Abfrage ausgelöst, während in einer anderen Sitzung eine Abfrage ausgelöst wird, um die Daten zu laden.
- Der First Level Cache von Hibernate kann alte Werte enthalten. Wie oben zu sehen, habe ich mein Programm für 10 Sekunden in den Ruhezustand versetzt und in dieser Zeit den Wert (Name von Pankaj zu PankajK) in der Datenbank aktualisiert. Dies wurde jedoch nicht in derselben Sitzung angezeigt. In einer anderen Sitzung haben wir jedoch den aktualisierten Wert erhalten.
- Wir können die Methode
session.evict()
verwenden, um ein einzelnes Objekt aus dem First Level Cache von Hibernate zu entfernen. - Wir können die Methode
session.clear()
verwenden, um den Cache zu leeren, d. h. alle Objekte aus dem Cache zu löschen. - Wir können die Methode
session.contains()
verwenden, um zu überprüfen, ob ein Objekt im Hibernate-Cache vorhanden ist oder nicht. Wenn das Objekt im Cache gefunden wird, gibt estrue
zurück, andernfallsfalse
. - Da Hibernate alle Objekte im First Level Cache der Sitzung zwischenspeichert, ist es bei der Ausführung von Massenabfragen oder Batch-Updates notwendig, den Cache in bestimmten Intervallen zu leeren, um Speicherprobleme zu vermeiden.
Das war’s zum Hibernate-Caching und First Level Cache Beispiel. In zukünftigen Beiträgen werden wir uns die Implementierung von Hibernate Second Level Cache – EHCache ansehen.