Implementieren Sie das Hibernate Second-Level Cache mit NCache

In diesem Tutorial werden wir die Implementierung eines zweiten Generations Caches in Hibernate mit NCache erkunden.

Wir werden eine Java-Anwendung mit Hibernate einrichten und NCache als zweiten Generations Cache einrichten. Schließlich werden wir die Implementierung testen, um zu sehen, wie das Caching die Datenbanklast verringert und die Leistung verbessert.

Grundlagen

Bevor wir uns der Implementierung widmen, lassen Sie uns die Grundlagen von Hibernate, NCache und dem Hibernate zweiten Generations Cache verstehen.

Hibernate

Hibernate ist ein open-source Objekt-Relationen-Mappings-(ORM)-Framework für Java-Anwendungen. Es vereinfacht die Entwicklung von Datenbankinteraktionen, indem es Java-Objekte mit Datenbanktabellen abbildet und umgekehrt.

Um die Leistung zu verbessern, bietet Hibernate zwei Arten von Caching an:

1. Erstes Generations Cache

Das erste Generations Cache ist mit der Hibernate Sitzung assoziiert und standardmäßig aktiviert. Es speichert die über eine Sitzung geholten Objekte und eliminiert das Notwendigkeiten, die Datenbank mehrmals für das gleiche Objekt anzurufen.

Das erste Generations Cache besitzt die Sitzungsscope und wird nicht über Sitzungen geteilt.

Es ist auch nicht persistent und wird geleert, wenn die Sitzung geschlossen oder explizit geleert wird.

2. Zweites Generations Cache

Der zweite Schicht-Cache ist zwischen Sitzungen geteilt und kann so konfiguriert werden, dass Daten auf Anwendungsebene zwischengespeichert werden. Er reduziert die Anzahl der Datenbankzugriffe, indem Objekte länger zwischengespeichert werden.

Der zweite Schicht-Cache muss explizit konfiguriert werden und kann mit verschiedenen Caching-Anbietern wie NCache, Ehcache usw. implementiert werden.

NCache

NCache ist eine verteilte Caching-Lösung für .NET und Java-Anwendungen. Es bietet einen In-Memory-DatenSpeicher, der zur Cacheingabe von oft aufgerufenen Daten und Verbesserung der Anwendungsleistung verwendet werden kann.

NCache unterstützt verschiedene Caching-Topologien wie repliziert, partitioniert und Client-Cache.

NCache kann als zweite Schicht-Cache in Hibernate verwendet werden, um Objekte im Cache zu speichern und aus dem Cache zu lesen, anstatt die Datenbank zu bearbeiten.

Code Setup

Lassen Sie uns mit der Erstellung einer Java-Anwendung beginnen und Hibernate so einstellen, dass es mit der Datenbank interagieren kann.

Wir werden Maven verwenden, um Abhängigkeiten zu verwalten und den Projekt zu bauen. Die Anwendung wird eine Entität Klasse haben, um Daten zu definieren und eine Kunden Klasse, um mit der Datenbank zu interagieren.

Zuerst werden wir die Anwendung ohne Caching testen, um die Datenbankinteraktionen zu sehen. Dann werden wir NCache als zweite Schicht-Cache in Hibernate konfigurieren, um Entitätsobjekte zu cachen und Datenbankzugriffe zu reduzieren.

Abhängigkeiten

Wir werden beginnen, die erforderlichen Abhängigkeiten für Hibernate und NCache im Datei pom.xml hinzuzufügen:

<dependencies> <!-- Hibernate dependencies --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>6.6.1.Final</version> </dependency> <!-- NCache dependencies --> <dependency> <groupId>com.alachisoft.ncache</groupId> <artifactId>ncache-hibernate</artifactId> <version>5.3.3</version> </dependency> </dependencies>

Bitte beachten Sie, dass die hier erwähnten Versionen möglicherweise aufgrund der letzten Veröffentlichungen variieren. Stellen Sie sicher, dass Sie die für Ihr Projekt passenden Versionen verwenden.

Entitätsklasse

Im nächsten Schritt erstellen wir eine Entitätsklasse, um die Daten, die wir cachen wollen, zu repräsentieren. Wir definieren eine einfache Customer-Klasse mit id– und name-Feldern:

@Entity @Cacheable @org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE, region = "CustomerRegion") public class Customer { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; // Getter und Setter }

Die Customer-Klasse ist mit @Entity und @Cacheable markiert, um sie als cachbare Entität zu definieren. Sie besitzt ein id-Feld, das mit @Id und @GeneratedValue markiert ist, um automatisch eindeutige Identifikatoren zu generieren.

Wir verwenden auch die @Cache-Annotation, um die Cachingstrategie und den Bereich für die Entität zu definieren.

NONSTRICT_READ_WRITE teilt Hibernate mit, dass beim Lesen oder Schreiben von Daten mit eventualer Kohärenz der Cache aktualisiert werden soll.

Das Attribut region gibt an, in welcher Cacheregion die Daten gespeichert werden.

Wir konfigurieren NCache, um in diesen Bereich zu speichern.

Hibernate-Konfiguration

Wir müssen Hibernate so einstellen, dass es mit der Datenbank interagiert und Caching aktiviert.

Legen wir nun eine hibernate.cfg.xml-Datei im Verzeichnis src/main/resources mit folgender Konfiguration an:

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property> <property name="hibernate.connection.url">jdbc:oracle:thin:@localhost:1521:xe</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">password</property> <property name="hibernate.dialect">org.hibernate.dialect.Oracle12cDialect</property> <property name="hibernate.hbm2ddl.auto">update</property> <property name="hibernate.show_sql">true</property> </session-factory> </hibernate-configuration>

In dieser Konfigurationsdatei geben wir die Datenbankverbindungsdetails, den Dialekt und die Cacheeinstellungen an. Wir verwenden Oracle als Datenbank und konfigurieren Hibernate, um das Schema automatisch zu aktualisieren.

Kundenklasse

Wir erstellen eine Kundenklasse, um mit der Datenbank zu interagieren und die Cachemechanismus zu testen. Wir können eine main Klasse schreiben, um mit Hibernate Customer Objekte zu speichern und abzurufen:

public class HibernateClient { public static void main(String[] args) { SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory(); Session session = sessionFactory.openSession(); Transaction transaction = session.beginTransaction(); Customer customer = new Customer(); customer.setName("John Doe"); session.save(customer); transaction.commit(); session.close(); session = sessionFactory.openSession(); transaction = session.beginTransaction(); Customer retrievedCustomer = session.get(Customer.class, customer.getId()); System.out.println("Retrieved Customer: " + retrievedCustomer.getName()); transaction.commit(); session.close(); session = sessionFactory.openSession(); transaction = session.beginTransaction(); retrievedCustomer = session.get(Customer.class, customer.getId()); System.out.println("Retrieved Customer: " + retrievedCustomer.getName()); transaction.commit(); session.close(); } }

In dieser Kundenklasse erstellen wir eine SessionFactory, indem wir die Hibernate-Konfiguration verwenden und eine Sitzung öffnen, um mit der Datenbank zu interagieren. Wir speichern ein Customer Objekt in der Datenbank und holen es mit dem id wieder her raus.

Dann rufen wir die retrieveCustomer Methode zweimal in zwei separaten Sitzungen auf, um zu sehen, wie sich die Datenbankinteraktionen ohne Caching verhalten.

Wir werden beobachten, dass sich die gleiche Objekt zweimal aus der Datenbank holen lassen:

Wie wir sehen können, ist die Hibernate Abfrage zweimal ausgeführt worden.

Einrichten des NCache Servers

Um NCache als zweiten Cachelevel in Hibernate zu verwenden, müssen wir einen NCache Server einrichten und configureieren, um die zwischengespeicherten Daten aufzuladen.

NCache bietet eine verteilte Cachinglösung, die auf Windows und Linux-Server installiert werden kann. Wir werden ein Cache-Cluster mit NCache erzeugen und es konfigurieren. Sobald das Cache-Cluster eingerichtet ist, können wir davon aus unserer Java-Anwendung ausgehen.

Aktivieren von NCache als zweites Cachelevel in Hibernate

Sobald der NCache Server eingerichtet ist, können wir Hibernate so einstellen, dass es NCache als zweiten Cachelevel-Provider verwendet. Wir werden die Hibernate-Konfigurationsdatei aktualisieren und die Cacheeinstellungen angeben, um Caching zu aktivieren.

Aktivieren von Cache-Bereichen

Lassen Sie uns die Cacheeinstellungen im Datei hibernate.cfg.xml aktualisieren, um NCache als Zweitüberschreibungs-Cache-Provider zu aktivieren:

<hibernate-configuration> <session-factory> <property name="hibernate.cache.use_second_level_cache">true</property> <property name="hibernate.cache.region.factory_class">com.alachisoft.ncache.NCacheRegionFactory</property> ... </session-factory> </hibernate-configuration>

Hier setzen wir die Eigenschaft hibernate.cache.use_second_level_cache auf true, um den Zweitüberschreibungs-Cache zu aktivieren. Wir definieren auch die Eigenschaft hibernate.cache.region.factory_class, um die NCacheRegionFactory als Cacheprovider zu verwenden, die eine Implementierung der JCacheRegionFactory ist.

NCache-Eigenschaften konfigurieren

NCache bietet eine Reihe von Eigenschaften, um die Cacheeinstellungen in Hibernate zu konfigurieren. Wir können diese in der Datei ncache-hibernate.xml angeben:

<configuration> <application-config application-id="myapp" enable-cache-exception="true" default-region-name="DefaultRegion" key-case-sensitivity="false"> <cache-regions> <region name="CustomerRegion" cache-name="demoCache" priority="AboveNormal" expiration-type="Sliding" expiration-period="8"/> <region name="DefaultRegion" cache-name="demoCache" priority="default" expiration-type="None" expiration-period="0"/> </cache-regions> <database-dependencies> <dependency entity-name="hibernator.BLL.Customer" type="oledb" sql-statement="SELECT CustomerID FROM Customers WHERE CustomerID ='?';" cache-key-format="Customers#[pk]" connection-string="Provider=SQLOLEDB;Data Source=20.200.20.40,1433;Initial Catalog=Northwind;User ID=john;Password=1234;"/> </database-dependencies> </application-config> </configuration>

In dieser Konfigurationsdatei definieren wir den Cachebereich CustomerRegion mit dem Cachenamen, der Priorität, dem Verfallsmodus und der Verfallsdauer. Wir setzen den expiration-type auf Sliding mit einer Verfallsdauer von 8 Sekunden. Dies bedeutet, dass die zwischengespeicherten Daten nach 8 Sekunden Inaktivität abgelaufen sind und aus dem Cache entfernt werden.

Zusätzlich definieren wir eine DefaultRegion, die mit Standardeinstellungen für andere Entitäten versehen ist, die keinen spezifischen Cachebereich haben. Dies wird als Standardbereich für Entitäten verwendet, die nicht explizit konfiguriert sind.

Having multiple cache regions allows us to define different cache settings for different entities based on their requirements.

Nächstes Definieren wir eine Datenbankabhängigkeit für die Entität Kunden. Dies wird verwendet, um den Zugriff auf die Zwischenspeicherung mit der Datenbank zu synchronisieren und die Zwischenspeicherung zu aktualisieren oder zu entfernen, wenn Änderungen in der Datenbank vorgenommen werden.

Wir legen die SQL-Anweisung fest, um das Kundenkennung aus der Kunden-Tabelle zu holen und die Verbindungszeichenfolge, um mit der Datenbank verbunden zu werden.

Der Zwischenspeicher-Schlüsselformat legt fest, wie der Zwischenspeicher-Schlüssel basierend auf der Primärschlüssel der Entität generiert wird.

Testen

Nun, da wir NCache als zweite Ebene des Zwischenspeichers in Hibernate konfiguriert haben, testen wir die Anwendung, um zu sehen, wie der Zwischenspeicher die Leistung verbessert. Wir führen die Clientklasse erneut aus und beobachten die Datenbankinteraktionen mit aktiviertem Zwischenspeicher.

Wenn wir die Clientklasse ausführen, sehen wir, dass der erste Aufruf, um das Kunden-Objekt zu holen, die Datenbank anruft, um die Daten abzurufen. Allerdings holt der zweite Aufruf, um das gleiche Objekt zu holen, es aus dem Zwischenspeicher statt aus der Datenbank. Dies demonstriert, wie der Zwischenspeicher die Datenbanklast verringert und die Leistung verbessert, indem Daten aus dem Zwischenspeicher bereitgestellt werden.

Vorteile von NCache mit Hibernate verwenden

Der Einsatz von NCache als zweite Ebene des Zwischenspeichers in Hibernate bietet verschiedene Vorteile:

  • Verbesserte Leistung: NCache bietet schnelles In-Memory-Speicher für zwischengespeicherte Daten, was Latenzzeiten reduziert und die Durchsatzleistung verbessert. Es bietet auch asynchronen Vorgänge an, um den Cache im Hintergrund zu aktualisieren, was den Einfluss auf die Leistung der Anwendung verringern kann.
  • Skalierbarkeit: Während sich die Anwendung skaliert, kann NCache horizontal skalieren, um große Datenmengen und Benutzeranfragen zu verarbeiten. Es kann in einem Cluster deployiert werden und unterstützt Features wie Cache-Replikation und Partitionierung, um die Last zu verteilen.
  • Flexibilität: NCache bietet verschiedene Caching-Topologien und -Konfigurationen, um auf die unterschiedlichen Anforderungen von Anwendungen abzugleichen. Darüber hinaus ermöglicht die Verwendung von Cache-Bereichen, dass unterschiedliche Entitäten unterschiedliche Cache-Einstellungen basierend auf ihren Bedürfnissen haben können. Dies ermöglicht eine feingranulare Kontrolle über das Caching-Verhalten.
  • Synchronisierung: NCache bietet die Option zur Datenbank-Synchronisierung an, um den Cache mit der Datenbank zu synchronisieren. Dies stellt sicher, dass die zwischengespeicherten Daten aktuell sind und die neuesten Änderungen in der Datenbank widerspiegeln.

Zusammenfassung

In diesem Tutorial haben wir die Implementierung eines Zweitglied-Caches in Hibernate mit NCache für Java-Anwendungen erforscht.

Wir haben begann, indem wir die Grundlagen von Hibernate, NCache und dem Hibernate Zweitglied-Cache verstanden. Dann haben wir ein Java-Anwendung mit Hibernate aufgebaut und NCache als Zweitglied-Cache konfiguriert. Schließlich haben wir die Implementierung getestet, um zu sehen, wie das Caching die Leistung verbessert, indem es Anfragen an die Datenbank verringert und Daten aus dem Cache bereitstellt.

Durch die Verwendung von NCache mit Hibernate können Entwickler die Leistung, Skalierbarkeit und Verlässlichkeit ihrer Anwendungen verbessern, indem sie auf die Stärken von verteilten Caching nutzen. NCache bietet eine robuste Cachinglösung, die problemlos mit Hibernate und anderen Java-Frameworks integriert und somit eine ideale Wahl für die Datencaching in Java-Anwendungen ist.

Source:
https://dzone.com/articles/implement-hibernate-second-level-cache-with-ncache