Hibernate - Bộ nhớ đệm

Bộ nhớ đệm là một cơ chế để nâng cao hiệu suất của hệ thống. Nó là một bộ nhớ đệm nằm giữa ứng dụng và cơ sở dữ liệu. Bộ nhớ đệm lưu trữ các mục dữ liệu được sử dụng gần đây để giảm số lần truy cập cơ sở dữ liệu càng nhiều càng tốt.

Bộ nhớ đệm cũng quan trọng đối với Hibernate. Nó sử dụng một lược đồ bộ nhớ đệm đa cấp như được giải thích bên dưới:

Bộ nhớ đệm cấp một

Bộ đệm cấp đầu tiên là bộ đệm Phiên và là bộ đệm bắt buộc mà qua đó tất cả các yêu cầu phải vượt qua. Đối tượng Session giữ một đối tượng dưới quyền riêng của nó trước khi đưa nó vào cơ sở dữ liệu.

Nếu bạn phát hành nhiều bản cập nhật cho một đối tượng, Hibernate cố gắng trì hoãn việc cập nhật càng lâu càng tốt để giảm số lượng các câu lệnh SQL cập nhật được phát hành. Nếu bạn đóng phiên, tất cả các đối tượng đang được lưu trong bộ nhớ cache sẽ bị mất và vẫn tồn tại hoặc được cập nhật trong cơ sở dữ liệu.

Bộ nhớ đệm cấp hai

Bộ đệm cấp hai là bộ đệm tùy chọn và bộ đệm cấp một sẽ luôn được hỏi ý kiến ​​trước khi thực hiện bất kỳ nỗ lực nào để định vị một đối tượng trong bộ đệm cấp hai. Bộ đệm ẩn mức thứ hai có thể được định cấu hình trên cơ sở mỗi lớp và mỗi tập hợp và chịu trách nhiệm chính cho việc lưu trữ các đối tượng trong các phiên.

Bất kỳ bộ đệm nào của bên thứ ba đều có thể được sử dụng với Hibernate. Anorg.hibernate.cache.CacheProvider được cung cấp, giao diện này phải được triển khai để cung cấp cho Hibernate xử lý việc triển khai bộ đệm.

Bộ nhớ cache cấp truy vấn

Hibernate cũng thực hiện một bộ đệm cho các tập kết quả truy vấn tích hợp chặt chẽ với bộ đệm cấp hai.

Đây là một tính năng tùy chọn và yêu cầu hai vùng bộ nhớ cache vật lý bổ sung để lưu giữ kết quả truy vấn được lưu trong bộ nhớ cache và dấu thời gian khi bảng được cập nhật lần cuối. Điều này chỉ hữu ích cho các truy vấn được chạy thường xuyên với các tham số giống nhau.

Bộ nhớ đệm cấp độ thứ hai

Hibernate sử dụng bộ nhớ cache cấp một theo mặc định và bạn không phải làm gì để sử dụng bộ nhớ cache cấp một. Hãy đi thẳng đến bộ nhớ cache cấp hai tùy chọn. Không phải tất cả các lớp đều được hưởng lợi từ bộ nhớ đệm, vì vậy điều quan trọng là có thể tắt bộ đệm cấp hai.

Bộ đệm ẩn cấp hai Hibernate được thiết lập theo hai bước. Đầu tiên, bạn phải quyết định sử dụng chiến lược đồng thời nào. Sau đó, bạn định cấu hình các thuộc tính hết hạn bộ nhớ cache và bộ nhớ cache vật lý bằng cách sử dụng nhà cung cấp bộ nhớ cache.

Các chiến lược đồng thời

Chiến lược đồng thời là một trung gian, chịu trách nhiệm lưu trữ các mục dữ liệu trong bộ đệm và truy xuất chúng từ bộ đệm. Nếu bạn định kích hoạt bộ nhớ cache cấp hai, bạn sẽ phải quyết định, đối với mỗi lớp và tập hợp liên tục, chiến lược đồng thời bộ nhớ cache nào sẽ sử dụng.

  • Transactional - Sử dụng chiến lược này cho dữ liệu hầu như chỉ đọc, nơi điều quan trọng là ngăn chặn dữ liệu cũ trong các giao dịch đồng thời, trong trường hợp hiếm hoi là cập nhật.

  • Read-write - Một lần nữa sử dụng chiến lược này cho dữ liệu hầu như chỉ đọc, trong đó điều quan trọng là phải ngăn chặn dữ liệu cũ trong các giao dịch đồng thời, trong trường hợp hiếm hoi là cập nhật.

  • Nonstrict-read-write- Chiến lược này không đảm bảo tính nhất quán giữa bộ đệm và cơ sở dữ liệu. Sử dụng chiến lược này nếu dữ liệu hầu như không bao giờ thay đổi và khả năng nhỏ là dữ liệu cũ không đáng lo ngại.

  • Read-only- Một chiến lược đồng thời phù hợp với dữ liệu, không bao giờ thay đổi. Chỉ sử dụng nó cho dữ liệu tham khảo.

Nếu chúng tôi định sử dụng bộ nhớ đệm cấp hai cho Employee lớp, hãy để chúng tôi thêm phần tử ánh xạ cần thiết để yêu cầu Hibernate lưu vào bộ nhớ cache các cá thể của Nhân viên bằng chiến lược đọc-ghi.

<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 
<hibernate-mapping>
   <class name = "Employee" table = "EMPLOYEE">
      
      <meta attribute = "class-description">
         This class contains the employee detail. 
      </meta>
      
      <cache usage = "read-write"/>
      
      <id name = "id" type = "int" column = "id">
         <generator class="native"/>
      </id>
      
      <property name = "firstName" column = "first_name" type = "string"/>
      <property name = "lastName" column = "last_name" type = "string"/>
      <property name = "salary" column = "salary" type = "int"/>
      
   </class>
</hibernate-mapping>

Thuộc tính use = "read-write" yêu cầu Hibernate sử dụng chiến lược đồng thời đọc-ghi cho bộ đệm được xác định.

Nhà cung cấp bộ nhớ đệm

Bước tiếp theo của bạn sau khi xem xét các chiến lược đồng thời, bạn sẽ sử dụng các lớp ứng viên bộ đệm của mình để chọn nhà cung cấp bộ đệm. Hibernate buộc bạn phải chọn một nhà cung cấp bộ nhớ cache duy nhất cho toàn bộ ứng dụng.

Sr.No. Tên & Mô tả bộ nhớ đệm
1

EHCache

Nó có thể cache trong bộ nhớ hoặc trên đĩa và bộ nhớ đệm theo cụm và nó hỗ trợ bộ nhớ đệm kết quả truy vấn Hibernate tùy chọn.

2

OSCache

Hỗ trợ bộ nhớ đệm vào bộ nhớ và đĩa trong một JVM với một bộ chính sách hết hạn phong phú và hỗ trợ bộ nhớ cache truy vấn.

3

warmCache

Bộ nhớ cache cụm dựa trên JGroups. Nó sử dụng tính năng vô hiệu hóa theo cụm, nhưng không hỗ trợ bộ đệm ẩn truy vấn Hibernate.

4

JBoss Cache

Bộ đệm phân cụm được sao chép hoàn toàn theo giao dịch cũng dựa trên thư viện đa hướng JGroups. Nó hỗ trợ sao chép hoặc vô hiệu hóa, giao tiếp đồng bộ hoặc không đồng bộ, và khóa lạc quan và bi quan. Bộ đệm ẩn truy vấn Hibernate được hỗ trợ.

Mọi nhà cung cấp bộ nhớ đệm không tương thích với mọi chiến lược đồng thời. Ma trận khả năng tương thích sau đây sẽ giúp bạn chọn một sự kết hợp thích hợp.

Chiến lược / Nhà cung cấp Chỉ đọc Không hạn chế đọc-ghi Đọc viết Giao dịch
EHCache X X X  
OSCache X X X  
SwarmCache X X    
JBoss Cache X     X

Bạn sẽ chỉ định một nhà cung cấp bộ nhớ cache trong tệp cấu hình hibernate.cfg.xml. Chúng tôi chọn EHCache làm nhà cung cấp bộ nhớ đệm cấp hai của mình -

<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM 
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
   <session-factory>
   
      <property name = "hibernate.dialect">
         org.hibernate.dialect.MySQLDialect
      </property>
   
      <property name = "hibernate.connection.driver_class">
         com.mysql.jdbc.Driver
      </property>
   
      <!-- Assume students is the database name -->
   
      <property name = "hibernate.connection.url">
         jdbc:mysql://localhost/test
      </property>
   
      <property name = "hibernate.connection.username">
         root
      </property>
   
      <property name = "hibernate.connection.password">
         root123
      </property>
   
      <property name = "hibernate.cache.provider_class">
         org.hibernate.cache.EhCacheProvider
      </property>
   
      <!-- List of XML mapping files -->
      <mapping resource = "Employee.hbm.xml"/>
   
   </session-factory>
</hibernate-configuration>

Bây giờ, bạn cần xác định các thuộc tính của các vùng bộ nhớ cache. EHCache có tệp cấu hình riêng,ehcache.xml, phải nằm trong CLASSPATH của ứng dụng. Cấu hình bộ đệm trong ehcache.xml cho lớp Nhân viên có thể trông như thế này -

<diskStore path="java.io.tmpdir"/>

<defaultCache
maxElementsInMemory = "1000"
eternal = "false"
timeToIdleSeconds = "120"
timeToLiveSeconds = "120"
overflowToDisk = "true"
/>

<cache name = "Employee"
maxElementsInMemory = "500"
eternal = "true"
timeToIdleSeconds = "0"
timeToLiveSeconds = "0"
overflowToDisk = "false"
/>

Vậy là xong, bây giờ chúng ta đã bật bộ nhớ đệm cấp hai cho lớp Nhân viên và Ngủ đông, bây giờ sẽ truy cập bộ nhớ đệm cấp hai bất cứ khi nào bạn điều hướng đến Nhân viên hoặc khi bạn tải Nhân viên theo mã định danh.

Bạn nên phân tích tất cả các lớp của mình và chọn chiến lược bộ nhớ đệm thích hợp cho từng lớp. Đôi khi, bộ nhớ đệm cấp hai có thể hạ cấp hiệu suất của ứng dụng. Vì vậy, bạn nên chuẩn ứng dụng của mình trước, không bật bộ nhớ đệm và sau đó bật bộ nhớ đệm phù hợp của bạn và kiểm tra hiệu suất. Nếu bộ nhớ đệm không cải thiện hiệu suất hệ thống, thì không có ích gì khi bật bất kỳ loại bộ đệm nào.

Bộ nhớ cache cấp truy vấn

Để sử dụng bộ đệm truy vấn, trước tiên bạn phải kích hoạt nó bằng cách sử dụng hibernate.cache.use_query_cache="true"thuộc tính trong tệp cấu hình. Bằng cách đặt thuộc tính này thành true, bạn thực hiện Hibernate tạo các bộ đệm cần thiết trong bộ nhớ để giữ các bộ truy vấn và định danh.

Tiếp theo, để sử dụng bộ đệm truy vấn, bạn sử dụng phương thức setCacheable (Boolean) của lớp Query. Ví dụ -

Session session = SessionFactory.openSession();
Query query = session.createQuery("FROM EMPLOYEE");
query.setCacheable(true);
List users = query.list();
SessionFactory.closeSession();

Hibernate cũng hỗ trợ hỗ trợ bộ nhớ cache chi tiết rất tốt thông qua khái niệm vùng bộ nhớ cache. Vùng bộ nhớ cache là một phần của bộ nhớ cache được đặt tên.

Session session = SessionFactory.openSession();
Query query = session.createQuery("FROM EMPLOYEE");
query.setCacheable(true);
query.setCacheRegion("employee");
List users = query.list();
SessionFactory.closeSession();

Mã này sử dụng phương pháp để yêu cầu Hibernate lưu trữ và tìm kiếm truy vấn trong vùng nhân viên của bộ đệm.