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

Hibernate 二級緩存實戰:Ehcache 配置與註解驅動完整指南

     編輯:Java 相關知識

Hibernate 二級緩存 (Second-Level Cache) 是 SessionFactory 級別的實體/查詢緩存,能顯著減少數據庫訪問。Ehcache 作為 Hibernate 經典默認緩存提供者,成熟穩定、配置靈活。本文系統講解註解驅動配置、五大併發策略選型、區域自定義、磁盤持久化、查詢緩存協同,附完整可運行代碼與控制台驗證。

核心依賴




    org.hibernate
    hibernate-ehcache
    5.6.15.Final


Hibernate 配置啟用二級緩存



org.hibernate.cache.ehcache.EhCacheRegionFactory
true           
true                
org.hibernate.cache.ehcache.EhCacheRegionFactory
/ehcache.xml 

實體註解配置緩存策略


import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;

@Entity
@Cache(usage = CacheConcurrencyStrategy.READ_ONLY) // 關鍵:類級別啟用緩存
@Table(name = "t_region") // 只讀參考數據:省份、字典、配置
public class Region {
    @Id @GeneratedValue
    private Long id;
    private String name;
    private String code;
    // getter/setter...
}

五大併發策略深度對比與選型

策略枚舉適用場景併發機制性能數據一致性典型實體
NONE不緩存 (默認)----
READ_ONLY**絕不修改**的參考數據無鎖,直接讀緩存**最高**強一致 (數據不變)字典、配置、省市區、枚舉表
NONSTRICT_READ_WRITE極少修改 (小時級以上),允許臟讀異步失效,無嚴格鎖高最終一致 (短暫不一致)文章分類、標簽、低頻配置
READ_WRITE頻繁讀寫,需嚴格一致性**時間戳/版本鎖**,事務提交前加鎖中強一致 (事務隔離)用戶資料、訂單、商品庫存
TRANSACTIONALJTA 分佈式事務環境XA 事務參與,緩存即資源管理器低強一致 (分佈式)跨數據源業務、分佈式事務

選型鐵律:能用 READ_ONLY 絕不用其它 → 修改極低用 NONSTRICT_READ_WRITE → 必須強一致用 READ_WRITE → 分佈式事務才用 TRANSACTIONAL。

ehcache.xml 完整配置詳解





    
    

    
    
        eternal="false"                  
        overflowToDisk="true"            
        timeToIdleSeconds="300"          
        timeToLiveSeconds="600"          
        diskPersistent="false"           
        diskExpiryThreadIntervalSeconds="120" 
        memoryStoreEvictionPolicy="LRU"  
    />

    
    
        maxElementsInMemory="5000"
        eternal="true"                  
        overflowToDisk="false"
        timeToIdleSeconds="0"
        timeToLiveSeconds="0"
    />

    

    
    

    
    

查詢緩存使用:關鍵步驟


// 1. 實體已配置 @Cache
// 2. SessionFactory 級別開啟 use_query_cache=true
// 3. 查詢時顯式啟用
Session session = sessionFactory.openSession();
Query query = session.createQuery("from Region where code = :code", Region.class);
query.setParameter("code", "BJ");
query.setCacheable(true);                    // 關鍵:啟用查詢緩存
query.setCacheRegion("custom.region.query"); // 可選:指定自定義查詢緩存區域
List list = query.list();            // 首次查數據庫,後續走緩存

// 驗證:控制台只打印一次 SQL
// Hibernate: select ... from t_region where code=?
// Region: Beijing
// Region: Beijing (第二次無 SQL)

控制台驗證輸出解讀


// 第一次查詢
Hibernate: select r.id, r.name, r.code from t_region r where r.code=?
Region: Beijing

// 第二次查詢 (命中查詢緩存 + 實體緩存)
// 無 SQL 輸出!
Region: Beijing

// 磁盤文件檢查 (overflowToDisk=true 且內存滿時)
/tmp/
  com.example.entity.Region.data          (實體緩存數據)
  com.example.entity.User.data
  org.hibernate.cache.internal.StandardQueryCache.data (查詢緩存)
  org.hibernate.cache.spi.UpdateTimestampsCache.data   (時間戳)

進階:自定義緩存區域名稱與策略


@Entity
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region = "user.cache.region")
public class User { ... }

// 查詢指定區域
query.setCacheRegion("user.cache.region"); // 實體緩存區域名
// 或獨立查詢緩存區域
query.setCacheRegion("custom.query.region");

避坑指南

坑點現象解決
忘記 use_query_cache=true查詢緩存不生效,每次發 SQL配置文件明確啟用
實體無 @Cache二級緩存不存儲實體,查詢緩存無法命中實體實體類添加註解
READ_WRITE 實體無版本鎖併發修改導致緩存不一致實體添加 @Version 樂觀鎖
集合緩存未配置一對多集合每次查數據庫關聯端添加 @Cache
緩存區域名稱衝突不同實體共用區域導致數據混亂顯式指定 region 屬性
集群環境單機 Ehcache多節點緩存不一致遷移至 Ehcache 3 + Terracotta / Redis / Hazelcast 分佈式緩存
事務提交前緩存可見未提交數據被其他事務讀到 (READ_WRITE 有鎖保護)確保事務隔離級別、正確使用 @Transactional

總結

Hibernate + Ehcache 二級緩存通過實體註解 @Cache + 併發策略選型 + 區域精細配置 + 查詢緩存協同,實現透明的數據庫訪問加速。核心原則:參考數據 READ_ONLY、業務數據 READ_WRITE+版本鎖、查詢緩存顯式啟用、集群環境換分佈式緩存。配置完畢後,通過控制台 SQL 輸出驗證「二次查詢無 SQL」是最直觀的成功標誌。

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