二級快取屬於 **SessionFactory 級別**,跨越多個 Session 生命週期。當同一個 SessionFactory 下的不同 Session 請求相同資料時,第二個 Session 可直接從二級快取取得,無須查詢資料庫,大幅提升高併發場景下的讀取效能。
Hibernate 內建 HashtableCacheProvider 僅供測試,生產環境建議使用 **Ehcache**。
<property name="hibernate.cache.provider_class">
org.hibernate.cache.EhCacheProvider
</property>
需額外引入 ehcache.jar。
在 User.hbm.xml 的 <class> 標籤下加入:
<cache usage="read-write"/>
usage 四種策略:
不同快取提供者支援的策略不同,請參閱官方文件對照表。
放在 classpath 根目錄:
<ehcache>
<diskStore path="java.io.tmpdir"/>
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
/>
</ehcache>
Session session1 = sessionFactory.openSession();
User user1 = (User) session1.load(User.class, 1);
user1.getName(); // 觸發載入
session1.close();
Session session2 = sessionFactory.openSession(); // 新 Session
User user2 = (User) session2.load(User.class, 1); // 直接從二級快取取得
user2.getName();
session2.close();
無二級快取時: 兩次 load 皆發出 select ... from user where id=?。
啟用後: 第二次 load **零 SQL**,直接回傳快取物件。
當資料經由外部系統異動,或需強制刷新時,可呼叫:
sessionFactory.evict(User.class, userId); // 清除特定實體
sessionFactory.evict(User.class); // 清除整個實體類別
sessionFactory.evictCollection("User.emails"); // 清除集合快取
<set>/<list> 等標籤上另行加入 <cache usage="..."/>。