首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

深入解析 Hibernate 框架的一級與二級緩存機制

     編輯:Java 相關知識

Hibernate 緩存機制概述

Hibernate 作為主流的 ORM 框架,其緩存機制是提升應用性能的關鍵。緩存分為一級緩存(Session 級)與二級緩存(SessionFactory 級),合理運用可大幅減少資料庫交互次數。

實體對象的三種狀態

在理解緩存前,必須先掌握 Hibernate 實體對象的三種狀態:

  • Transient(瞬時態):對象剛創建,未與資料庫記錄關聯,無 ID 值。
  • Persistent(持久態):對象已關聯 Session,擁有 ID,任何變更會自動同步至資料庫。
  • Detached(遊離態):Session 關閉後,對象仍有 ID 但不再受 Session 管理,修改不會自動同步。

狀態轉換示例

Transaction tx = session.beginTransaction();
User user = new User(); 
user.setName("shun");           // Transient 狀態
session.save(user); 
tx.commit();                    // 轉為 Persistent 狀態
session.close();                // 轉為 Detached 狀態

Session session2 = sessionFactory.openSession();
tx = session2.beginTransaction();
user.setName("shun123");
session2.saveOrUpdate(user);    // 重新變為 Persistent 狀態
tx.commit();
session2.close();

一級緩存(Session 緩存)

一級緩存是內建且強制啟用的,生命週期與 Session 綁定。同一 Session 內重複查詢相同 ID 的實體,會直接從緩存返回,不再發送 SQL。

驗證一級緩存效果

Session session = sessionFactory.openSession();
User user1 = (User) session.load(User.class, 29L);
System.out.println(user1.getName());
User user2 = (User) session.load(User.class, 29L); // 不會發送第二條 SQL
System.out.println(user2.getName());
session.close();

輸出顯示只執行了一條 SELECT 語句。若手動調用 session.evict(user) 移除緩存,再次查詢則會重新查詢資料庫。

二級緩存(SessionFactory 級緩存)

二級緩存跨 Session 共享,需顯式啟用並配置緩存提供者(如 EhCache)。

配置步驟

  1. 在 hibernate.cfg.xml 中啟用並指定提供者:
    <property name="hibernate.cache.use_second_level_cache">true</property>
    <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
  2. 提供 ehcache.xml 配置文件:
    <ehcache>
      <diskStore path="java.io.tmpdir"/>
      <defaultCache maxElementsInMemory="10000" eternal="false" 
                    timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" />
    </ehcache>
  3. 在映射文件或實體類上聲明緩存策略:<cache usage="read-write"/>

查詢緩存

查詢緩存需額外啟用 hibernate.cache.use_query_cache=true,並在查詢時調用 query.setCacheable(true)。適用於參數固定、頻繁執行的查詢。

二級緩存驗證示例

// 第一個 Session
Session session = sessionFactory.openSession();
Query query = session.createQuery("from User where name = 'shun123'");
query.setCacheable(true);
Iterator iter = query.iterate();
while(iter.hasNext()) System.out.println(((User)iter.next()).getName());
session.close();

// 第二個 Session(共享 SessionFactory)
Session session2 = sessionFactory.openSession();
Query query2 = session2.createQuery("from User where name = 'shun123'");
query2.setCacheable(true);
Iterator iter2 = query2.iterate(); // 不再查詢資料庫
while(iter2.hasNext()) System.out.println(((User)iter2.next()).getName());
session2.close();

第二次查詢直接從二級緩存獲取 ID,避免了資料庫交互。

注意事項

  • list() 方法不讀取查詢緩存(只寫),需使用 iterate() 或配合 setCacheable(true) 的 list()。
  • Criteria 查詢同樣支持 setCacheable(true)。
  • 實體類必須實現 Serializable 接口才能被二級緩存。

總結

一級緩存自動生效,二級緩存需配置。合理使用可顯著降低資料庫負載,但需注意緩存一致性與過期策略,避免髒讀問題。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved