三大持久化狀態
| 狀態 | 定義 | OID | Session 緩存 | 資料庫記錄 | 典型場景 |
| 瞬時態 | new 出來,未關聯 Session | 無 | 無 | 無 | new User() |
| 持久態 | 關聯 Session,納入一級緩存 | 有 | 有 | 有(或即將同步) | session.save(user) |
| 游離態 | Session 關閉/清理/evict,脫離管理 | 有 | 無 | 有 | session.close() 後 |
狀態轉換圖解
new User() ──save()──▶ 持久態 ──close()/evict()──▶ 游離態
▲ │
│ ▼
└────── update()/saveOrUpdate() ◀── 游離態
關鍵特性:持久態自動髒檢查
Session session = sf.openSession();
Transaction tx = session.beginTransaction();
User u = session.get(User.class, 1L); // 持久態
u.setName("New Name"); // 修改屬性
// 無需呼叫 update()!
tx.commit(); // 提交時自動發送 UPDATE SQL
session.close();
原理:Session 快照機制,提交時比較快照與當前狀態,生成 UPDATE。
一級緩存(Session 級)
- 生命週期:與 Session 同生共死,預設開啟,不可關閉。
- 作用域:事務級/請求級。
- 核心 API:
• evict(obj):移除指定對象
• clear():清空整個緩存
- 驗證:同一 Session 內重複
get() 同一 ID,只發 1 條 SQL。
二級緩存(SessionFactory 級)
啟用步驟
- 配置提供者(以 EhCache 3.x 為例)
hibernate.cache.use_second_level_cache=true
hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory
- 聲明實體緩存策略
註解方式:@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
XML 方式:<class-cache class="..." usage="read-write"/>
- 配置 ehcache.xml
設定 maxEntriesLocalHeap、timeToLiveSeconds、overflowToDisk 等。
四種併發策略選型
| 策略 | 適用場景 | 特點 |
READ_ONLY | 從不修改的參考數據(字典、配置) | 最高效、最安全 |
NONSTRICT_READ_WRITE | 極少修改、允許極小概率臟讀 | 無鎖、性能好 |
READ_WRITE | 常規業務數據、需強一致性 | 軟鎖、支援事務隔離 |
TRANSACTIONAL | JTA 環境、需 XA 事務 | 完全事務語義、效能最低 |
二級緩存工作流程
- ID 查詢(
get/load) → 一級緩存 → 二級緩存 → 資料庫
- 條件查詢(
list/iterate) → 不走二級緩存(除非開啟查詢緩存)
- 增刪改 → 同步更新一級、二級緩存
查詢緩存
- 針對普通屬性/標量結果集緩存;實體查詢僅緩存 ID,實體仍走二級緩存。
- 啟用:
hibernate.cache.use_query_cache=true + query.setCacheable(true)。
- 依賴二級緩存,建議同時開啟。
什麼數據適合進二級緩存?
| ✅ 適合 | ❌ 不適合 |
| 字典表、配置表、郵編、貨幣匯率 | 訂單、庫存、賬戶餘額(高併發寫入) |
| 權限菜單、組織架構(讀多寫少) | 跨應用共享表(緩存一致性難保證) |
| 靜態參考數據(幾乎不變) | 財務核心數據(零容忍臟讀) |
緩存清理 API
// SessionFactory 級
sf.evict(Entity.class); // 清除某實體所有
sf.evict(Entity.class, id); // 清除指定 ID
sf.evictCollection("Entity.field"); // 清除集合緩存
總結
掌握 三態轉換 是用好 Hibernate 的前提;一級緩存自動透明,二級緩存需顯式配置策略。生產環境建議:
1. 參考數據 → READ_ONLY + 二級緩存
2. 核心業務實體 → READ_WRITE + 謹慎開啟二級緩存
3. 複雜報表查詢 → 關閉二級/查詢緩存,走原生 SQL + 手動分頁
4. 監控緩存命中率(EhCache/JMX),命中率 < 80% 時重新評估策略。