屬于SessionFactory級(jí)別的緩存嚣崭,可以在多個(gè)session之間共享數(shù)據(jù)。
實(shí)用場(chǎng)合
1.公開(kāi)的數(shù)據(jù), 數(shù)據(jù)基本上不發(fā)生變化
2.該數(shù)據(jù)保密性不是很強(qiáng)
3.需要引入第三 方的緩存工具,如 EhCache 等演侯。
生命周期
二級(jí)緩存的生命周期和sessionFactory是一致的。
開(kāi)發(fā)流程
1.1. 第一步:開(kāi)啟二級(jí)緩存
別忘記依賴
在核心配置hibernate.cfg.xml新增
<property name="hibernate.cache.use_second_level_cache">true</property>
啟用二級(jí)緩存,hibernate 二級(jí)緩存是一個(gè)規(guī)范接口,沒(méi)有實(shí)現(xiàn)
1.2. 第二步:指定二級(jí)緩存實(shí)現(xiàn)廠商
在核心配置hibernate.cfg.xml新增,實(shí)現(xiàn)廠商眯漩。
設(shè)置二級(jí)緩存的供應(yīng)商 Idea中沒(méi)有這個(gè)key的提示需手動(dòng)輸入
<property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
1.3. 第三步:在映射文件中開(kāi)啟具體的緩存支持
*.hbm.xml中指定哪個(gè)類(lèi)開(kāi)啟二級(jí)緩存
二級(jí)緩存一般設(shè)置為只讀
二級(jí)緩存緩存的僅僅是對(duì)象,如果查詢出來(lái)的是對(duì)象的一部分屬性(返回Object[]),則不會(huì)加到緩存中去赦抖。
1.4. 第四步:開(kāi)發(fā)
第一次查詢舱卡,從DB取記錄,關(guān)閉Session.第二次新 session查詢队萤,沒(méi)有走DB轮锥,直接從二級(jí)緩存取得記錄。
public void testTwoCache(){
Session session1 = HibernateUtils.openSession();
Session session2 = HibernateUtils.openSession();
BookTypeEntity bookTypeEntity = session1.get(BookTypeEntity.class, 31L);
System.out.println(bookTypeEntity.getTypeName());
session1.close();
//第二次查詢 走二級(jí)緩存要尔,不查DB
BookTypeEntity bookTypeEntity2 = session2.get(BookTypeEntity.class, 31L);
System.out.println(bookTypeEntity2.getTypeName());
session2.close();
}
注意:這里的POJO可以不用序列化舍杜。但是如果這個(gè)對(duì)象需要存儲(chǔ)到具體的硬盤(pán)中的時(shí)候,是需要序列化盈电。
注意:測(cè)試二級(jí)緩存需要保持關(guān)聯(lián)表為默認(rèn)的延遲檢索機(jī)制lazy=true,因?yàn)榧虞d關(guān)聯(lián)表二級(jí)緩存支持不夠蝴簇。
不足: 二級(jí)緩存對(duì)于立即加載的支持還是很差的
測(cè)試:
現(xiàn)象:
第二次查詢還是發(fā)生的SQL查詢。
二級(jí)緩存不足:
1匆帚,非對(duì)象不存儲(chǔ)
查詢返回的不是對(duì)象,下面的HQL不會(huì)加載到二級(jí)緩存
Select stuName from StudentInfo
2熬词,關(guān)聯(lián)支持不太好
二級(jí)緩存,不能很好解決關(guān)聯(lián)表問(wèn)題吸重。需要把所有關(guān)聯(lián)的地方改為默認(rèn)的延遲檢索互拾,不找關(guān)聯(lián)表。
主要是主表的二級(jí)緩存需保持默認(rèn)lazy="true“
若關(guān)聯(lián)表兩邊都設(shè)置為false嚎幸,部分到二級(jí)緩存颜矿,有不成功的地方。
測(cè)試:session.get(BookInfo.class, 18L)
3嫉晶,不支持Query查詢
from BookInfo where bookId=:bookId
兩次都是從數(shù)據(jù)庫(kù)找記錄
查詢緩存
也是二級(jí)緩存,支持Query
查詢緩存也是sessionFactory級(jí)別的緩存:需要在二級(jí)緩存設(shè)置的基礎(chǔ)上添加
只有當(dāng)HQL語(yǔ)句完全相同骑疆,參數(shù)設(shè)置也相同才生效
生命周期:只要一些數(shù)據(jù)放入到查詢緩存中,該緩存會(huì)一直存在替废,直到緩存中的數(shù)據(jù)被修改了箍铭,該緩存的生命周期就結(jié)束了。
2.1. 第一步:前提條件
同上椎镣,必須先配置二級(jí)緩存
2.2. 第二步:開(kāi)啟查詢緩存
在核心配置Hibernate.cfg.xml中加入
<property name="hibernate.cache.use_query_cache">true</property>
2.3. 第三步:開(kāi)發(fā)的時(shí)候需要設(shè)置查詢緩存
HQL語(yǔ)句后設(shè)置開(kāi)啟
query.setCacheable(true);//開(kāi)啟查詢緩存
注意保持默認(rèn)的lazy=true(避免關(guān)聯(lián))
代碼:
public void testQueyCache(){
Session session1 = HibernateUtils.openSession();
Session session2 = HibernateUtils.openSession();
String hql = "from BookTypeEntity where typeId=:tid";
Query<BookTypeEntity> query = session1.createQuery(hql, BookTypeEntity.class);
query.setParameter("tid",31L);
//開(kāi)啟查詢緩存
query.setCacheable(true);
BookTypeEntity singleResult = query.getSingleResult();//獲取單條記錄
System.out.println(singleResult.getTypeName());
session1.close();
//第二次查詢
Query<BookTypeEntity> query2 = session2.createQuery(hql, BookTypeEntity.class);
query2.setParameter("tid",31L);
//開(kāi)啟查詢緩存
query2.setCacheable(true);
BookTypeEntity singleResult2 = query2.getSingleResult();//獲取單條記錄
System.out.println(singleResult2.getTypeName());
session2.close();
}
若修改數(shù)據(jù)或修改HQL的參數(shù)诈火,查詢緩存不生效.
查詢緩存就是讓Query可以從二級(jí)緩存獲得內(nèi)容。僅主表非關(guān)聯(lián)信息状答。
必須保持默認(rèn)的延遲檢索方式冷守。