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

Hibernate 二級快取完整配置指南:策略選擇、提供者設定與實體映射

     編輯:Java 相關知識

Hibernate 內建兩級快取機制:**一級快取 (Session 級)** 必然啟用、**二級快取 (SessionFactory 級)** 需顯式配置。正確使用二級快取能大幅降低資料庫存取、提升讀取效能。本文完整涵蓋:快取架構、並發策略選擇、EhCache 提供者配置、實體/集合映射、大量寫入快取管理。

一、快取架構對比

特性一級快取 (Session)二級快取 (SessionFactory)
生命週期交易/請求範圍應用程式全域 (跨 Session)
共享範圍單一 Session所有 Session 共享
儲存內容實體物件實例實體散裝資料 (脫離物件圖)
可關閉不可關閉可選擇性啟用/關閉
序列化要求不需要實體需實作 Serializable

二、一級快取管理:大量寫入避免 OOM

批次插入 10 萬筆資料時,Session 會快取所有實體導致 OutOfMemoryError。

解決方案:JDBC 批次 + 定期 flush/clear

<property name="hibernate.jdbc.batch_size">20</property>
Session session = HibernateUtil.currentSession();
Transaction tx = session.beginTransaction();
for (int i = 0; i < 100000; i++) {
    Student stu = new Student();
    session.save(stu);
    if (i % 20 == 0) {  // 每 20 筆 (batch_size)
        session.flush();  // 執行批次 INSERT
        session.clear();  // 清空 Session 快取,釋放記憶體
    }
}
tx.commit();

三、二級快取啟用步驟

  1. 選擇並發策略
  2. 配置快取提供者
  3. 實體/集合映射啟用快取

四、四大內建並發策略

策略隔離級別適用場景備註
transaction可重複讀受管環境 (JTA)、高讀低寫、極少更新JTA 環境專用
read-write讀已提交 (時間戳)高讀低寫、少量更新最常用
nonstrict-read-write不保證一致性極少更新、臟讀可接受需設足夠過期時間
read-only不可變永不變更的參考資料效能最佳

五、快取提供者選擇

推薦:單機/簡單叢集用 EhCache,完整叢集用 JBoss Cache/Infinispan。

六、EhCache 完整配置

hibernate.cfg.xml

<property name="hibernate.cache.provider_class">
  org.hibernate.cache.EhCacheProvider
</property>

ehcache.xml (放在 classpath 根目錄)

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

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

  <!-- 實體專屬配置 -->
  <cache name="com.example.entity.Student"
    maxElementsInMemory="10000"
    eternal="false"
    timeToIdleSeconds="300"
    timeToLiveSeconds="600"
    overflowToDisk="true"
  />

  <!-- 集合專屬配置 -->
  <cache name="com.example.entity.Group.students"
    maxElementsInMemory="5000"
    eternal="false"
    timeToIdleSeconds="300"
    timeToLiveSeconds="600"
    overflowToDisk="true"
  />
</ehcache>

屬性說明

  • maxElementsInMemory:記憶體最大物件數
  • eternal:true=永不過期 (忽略 TTL/TTI)
  • timeToIdleSeconds (TTI):閒置超過秒數淘汰
  • timeToLiveSeconds (TTL):建立後存活秒數淘汰
  • overflowToDisk:記憶體滿時溢寫磁碟

七、實體與集合映射啟用快取

Group.hbm.xml (一對多集合)

<class name="Group" table="t_group">
  <set name="students" ...>
    <cache usage="read-write"/>  <!-- 快取集合 (僅學生 ID) -->
    <key column="group_id"/>
    <one-to-many class="Student"/>
  </set>
</class>

Student.hbm.xml (實體快取)

<class name="Student" table="t_student">
  <cache usage="read-write"/>  <!-- 快取實體散裝屬性 -->
  <id .../>
  <property .../>
</class>

關鍵點

  • 集合快取 (<set>/<list> 上) 僅快取**關聯實體的 ID**
  • 實體快取 (<class> 上) 快取**完整散裝屬性**
  • **兩者皆需配置** 才能完整避免資料庫查詢

八、查詢快取 (Query Cache)

<property name="hibernate.cache.use_query_cache">true</property>
Query query = session.createQuery("from Student where age > :age");
query.setParameter("age", 18);
query.setCacheable(true);  // 啟用查詢快取
List<Student> list = query.list();

查詢快取儲存:**查詢參數 + 實體 ID 列表**,需配合實體快取使用。

九、快取失效與同步策略

提供者特性支援查詢快取叢集支援
EhCache純 Java、記憶體/磁碟、配置豐富✓✗ (需 Terracotta)
OSCache豐富過期策略、JGroups 叢集✓△
SwarmCache叢集快取 (JGroups)✗✓
JBoss Cache叢集快取、TreeCache✗✓

十、監控與調優

  • 啟用統計:hibernate.generate_statistics=true
  • 關鍵指標:second_level_cache_hit_ratio (命中率)、second_level_cache_put_count、second_level_cache_miss_count
  • 目標:讀多寫少實體命中率 > 90%
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
場景處理方式
應用程式更新實體Hibernate 自動更新/失效對應快取項
外部系統直接修改資料庫1. 縮短 TTL/TTI 2. 手動 sessionFactory.getCache().evictEntityRegion() 3. 資料庫觸發器通知
叢集環境使用支援叢集的提供者 (JBoss Cache/Infinispan) + 快取失效廣播