Hibernate 快取機制深度解析:一級快取、二級快取與查詢快取策略
Hibernate 快取是提升 ORM 效能的關鍵機制,透過減少資料庫存取頻率,大幅降低延遲與資料庫負載。本文系統整理一級快取(Session 級)、二級快取(SessionFactory 級)、查詢快取的運作原理、配置方式與最佳實踐策略。
什麼是快取?為何需要?
快取是將常用資料暫存在記憶體,降低對實體資料源(資料庫)存取頻率的策略。對 ORM 框架而言,資料庫存取效能直接決定應用執行速度,快取是優化的核心手段。評判 ORM 優劣的重要指標即資料庫存取頻次。
一級快取(Session 快取 / 會話級快取)
- 生命週期:與 Session 同生命週期,Session 關閉即銷毀
- 作用範圍:當前會話內
- 啟用方式:預設開啟,無法關閉
- 管理 API:
evict(Object):移除指定物件
clear():清空所有物件
query.list() vs query.iterate() 差異
| 方法 | 行為 | 快取使用 | SQL 執行次數 |
| list() | 單次 SQL 取回所有資料,存入快取 | 不使用一級快取查詢 | 每次呼叫皆執行 SQL |
| iterate() | 先取 ID,再逐筆查快取,缺漏再查 DB | 使用一級快取 | 最佳 1 次,最差 N+1 次 |
最佳組合:先呼叫 list() 將資料載入快取,後續同 Session 內呼叫 iterate() 直接命中快取,避免 N+1 問題。
二級快取(全域快取 / 應用級快取)
- 作用範圍:跨 Session,整個應用共享(SessionFactory 級)
- 啟用方式:預設關閉,需手動配置
- 實作元件:可插拔,預設 EhCache,支援 HashTable、OSCache、SwarmCache 等
EhCache 配置關鍵參數 (ehcache.xml)
<cache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
/>
maxElementsInMemory:記憶體最大物件數
eternal:是否永久不過期
timeToIdleSeconds:閒置超時時間(秒)
timeToLiveSeconds:生存時間(秒)
overflowToDisk:溢出是否寫入磁碟
Hibernate 配置啟用二級快取 (hibernate.cfg.xml)
<property name="hibernate.cache.use_second_level_cache">true</property>
<property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
實體類別啟用二級快取 (.hbm.xml 或註解)
<cache usage="read-only" region="Employee"/>
// 或 @Cache(usage = CacheConcurrencyStrategy.READ_ONLY, region = "Employee")
快取策略:read-only(唯讀)、read-write(讀寫)、nonstrict-read-write(非嚴格讀寫)、transactional(交易型)。
適合放入二級快取的資料特徵
- 極少修改的資料(字典表、配置表)
- 非關鍵資料,允許偶發髒讀
- 不會被併發存取的資料
- 參考資料
一級 vs 二級快取對比
| 維度 | 一級快取 | 二級快取 |
| 範圍 | Session 級 | SessionFactory 級(應用級) |
| 生命週期 | Session 存活期間 | 應用存活期間 |
| 共享性 | 不共享 | 全域共享 |
| 預設狀態 | 強制開啟 | 預設關閉 |
| 儲存內容 | 實體物件 | 實體物件、查詢結果 |
總結與策略建議
- 一級快取無需配置,善用
evict/clear 管理記憶體
- 二級快取需謹慎啟用,僅針對「讀多寫少、容忍度高」的實體
- 查詢快取(
hibernate.cache.use_query_cache=true)搭配二級快取使用,適用於固定參數的重複查詢
- 快取能提升檢索效能,但會增加記憶體壓力與一致性複雜度,必須根據業務場景制定失效策略
正確的快取策略 = 正確的資料分類 + 合適的快取層級 + 合理的失效機制。切記:快取不是銀彈,濫用反而拖垮效能。
- 上一篇文章: 高品質 Java 程式碼建議 65-69:陣列轉 List 陷阱、遍歷優化與集合相等性
- 下一篇文章: Java 泛型深度解析:型別擦除機制與 10 大限制實戰指南
Copyright ©
程式碼之家 All Rights Reserved