Hibernate二級快取是如何工作的?
快取有助於減少資料庫網路呼叫,以執行查詢。
一級快取與會話相關聯。它是隱式實現的。一級快取僅在會話物件存在時才存在。一旦會話物件終止/關閉,將不再存在快取物件。二級快取跨多個會話物件工作。它與會話工廠相關聯。二級快取物件可用於單個會話工廠中的所有會話。當特定會話工廠關閉時,這些快取物件將被終止。
實現二級快取
為了使用二級快取,我們需要新增以下依賴項。
<!-- https://mvnrepository.com/artifact/net.sf.ehcache/ehcache --> <dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache</artifactId> <version>2.10.9.2</version> </dependency> <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-ehcache --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-ehcache</artifactId> <version>5.4.32.Final</version> </dependency>
注意− hibernate ehcache 版本號必須與 hibernate 版本號相同。
現在,我們需要新增 hibernate 配置檔案,它將使 hibernate 連線到提供的資料庫並使用二級快取。
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <!-- JDBC Database connection settings --> <property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property> <property name="connection.url">jdbc:mysql://localhost:3306/demo?useSSL=false</property> <property name="connection.username">root</property> <property name="connection.password">root</property> <!-- JDBC connection pool settings ... using built-in test pool --> <property name="connection.pool_size">4</property> <!-- Echo the SQL to stdout --> <property name="show_sql">true</property> //caching properties <property name="cache.use_second_level_cache">true</property> <property name="cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property> <!-- Select our SQL dialect --> <property name="dialect">org.hibernate.dialect.MySQL5Dialect</property> <!-- Drop and re-create the database schema on startup --> <property name="hbm2ddl.auto">create-drop</property> <!-- name of annotated entity class --> <mapping class="academy.company.Parent"/> </session-factory> </hibernate-configuration>
示例
預設情況下,Java 中的所有實體都是未快取的。因此,要啟用實體的快取,我們在實體類 Parent 中使用 @Cacheable 和 @Cache 註解 -
import org.hibernate.annotations.CacheConcurrencyStrategy; import javax.persistence.*; @Entity @Table( name = " Employee") @Cacheable @org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_ONLY) public class Parent { @Id @GeneratedValue(strategy = GenerationType.AUTO) Long id; @Column(name = "first_name") String firstName; @Column(name = "last_name") String lastName; } Now, let’s check whether second level cache works: import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class Main { public static void main(String[] args) { SessionFactory sessionFactory = new Configuration() .configure("academy/company/hibernate.cfg.xml") .buildSessionFactory(); Session session1 = sessionFactory.openSession(); Parent parent1 = session1.get(Parent.class, 4); System.out.println(parent1.id + " " + parent1.firstName + " " + parent1.lastName); session1.close(); Session session2 = sessionFactory.openSession(); Parent parent2 = session2.get(Parent.class, 4); System.out.println(parent2.id + " " + parent2.firstName + " " + parent2.lastName); session2.close(); } }
輸出
Hibernate: select parent0.id as id1, parent0.first_name as first_name1, parent0.last_name as last_name1 from Parent parent0 where parent0.id=? 1 Subash Chopra 1 Subash Chopra
我們可以從控制檯清楚地看到,hibernate 在 session1 期間僅執行了一次查詢。現在,當 session2 訪問相同的查詢時,它不會向資料庫發出網路呼叫以執行它。相反,由於我們正在使用二級快取,它將從 session1 中獲取快取物件。
廣告