10、MyBatis的緩存
10.1、MyBatis的一級(jí)緩存
一級(jí)緩存是SqlSession級(jí)別的,通過(guò)同一個(gè)SqlSession對(duì)象 查詢的結(jié)果數(shù)據(jù)會(huì)被緩存,下次執(zhí)行相同的查詢語(yǔ)句,就 會(huì)從緩存中(緩存在內(nèi)存里)直接獲取,不會(huì)重新訪問(wèn)數(shù)據(jù)庫(kù)(數(shù)據(jù)庫(kù)在磁盤(pán)里),也就是說(shuō)就執(zhí)行一次sql。一級(jí)緩存 默認(rèn)開(kāi)啟。
使一級(jí)緩存失效的四種情況:
-
不同的SqlSession對(duì)應(yīng)不同的一級(jí)緩存
-
同一個(gè)SqlSession但是查詢條件不同
-
同一個(gè)SqlSession兩次查詢之間執(zhí)行了任意的增刪改操作 。
因?yàn)槿我庖淮卧鰟h改操作會(huì)清空所有SqlSession的所有緩存---為什么?因?yàn)槿我庖淮卧鰟h改可能會(huì)導(dǎo)致緩存的數(shù)據(jù)與增刪改后的數(shù)據(jù)庫(kù)中的數(shù)據(jù)不一致,我們肯定要以數(shù)據(jù)庫(kù)中的為準(zhǔn),這是mybatis的機(jī)制,自動(dòng)完成清空緩存。
-
同一個(gè)SqlSession兩次查詢期間手動(dòng)清空了緩存
sqlSession.clearCache();//手動(dòng)清空一級(jí)緩存。一級(jí)緩存是sqlSession級(jí)別的
例子:
10.2、MyBatis的二級(jí)緩存
二級(jí)緩存是SqlSessionFactory級(jí)別,通過(guò)同一個(gè)SqlSessionFactory創(chuàng)建的SqlSession對(duì)象 查詢的結(jié)果會(huì)被 緩存;此后若再次執(zhí)行相同的查詢語(yǔ)句,結(jié)果就會(huì)從緩存中獲取 。二級(jí)緩存不是默認(rèn)開(kāi)啟的,開(kāi)啟需滿足條件。
二級(jí)緩存開(kāi)啟的條件:
a>在核心配置文件中,設(shè)置全局配置屬性cacheEnabled=“true”,默認(rèn)為true,不需要設(shè)置
b>在映射文件中設(shè)置標(biāo)簽 <cache>
c>二級(jí)緩存必須在SqlSession關(guān)閉或提交之后有效
d>查詢的數(shù)據(jù)所轉(zhuǎn)換的實(shí)體類(lèi)類(lèi)型必須實(shí)現(xiàn)序列化的接口
使二級(jí)緩存失效的情況:
兩次查詢之間執(zhí)行了任意的增刪改操作,會(huì)使一級(jí)和二級(jí)緩存同時(shí)失效
咱自己創(chuàng)建的sqlSessionUtil工具類(lèi),每調(diào)一次,都新建一個(gè)SqlSessionFactory,然后再新建一個(gè)sqlSession。要想測(cè)試二級(jí)緩沖,可以自己直接寫(xiě),不使用工具類(lèi)。
@Test
public void testCache2() throws IOException {
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
//創(chuàng)建SqlSessionFactoryBuilder對(duì)象
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
//通過(guò)核心配置文件所對(duì)應(yīng)的字節(jié)輸入流創(chuàng)建工廠類(lèi)SqlSessionFactory,生產(chǎn)SqlSession對(duì)象
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
SqlSession sqlSession1 = sqlSessionFactory.openSession(true);
CacheMapper mapper1 = sqlSession1.getMapper(CacheMapper.class);
Emp emp1 = mapper1.getEmpByEmpId(1);
sqlSession1.close();
System.out.println(emp1);
SqlSession sqlSession2 = sqlSessionFactory.openSession(true);
CacheMapper mapper2 = sqlSession2.getMapper(CacheMapper.class);
Emp emp2 = mapper2.getEmpByEmpId(1);
System.out.println(emp2);
sqlSession2.close();
}
Emp要實(shí)現(xiàn)序列化
映射文件里要加一個(gè)<cache>標(biāo)簽
10.3、二級(jí)緩存的相關(guān)配置
了解
在mapper配置文件中添加的cache標(biāo)簽可以設(shè)置一些屬性:
①eviction屬性:緩存回收策略,默認(rèn)的是 LRU。
LRU(Least Recently Used) – 最近最少使用的:移除最長(zhǎng)時(shí)間不被使用的對(duì)象。
FIFO(First in First out) – 先進(jìn)先出:按對(duì)象進(jìn)入緩存的順序來(lái)移除它們。
SOFT – 軟引用:移除基于垃圾回收器狀態(tài)和軟引用規(guī)則的對(duì)象。
WEAK – 弱引用:更積極地移除基于垃圾收集器狀態(tài)和弱引用規(guī)則的對(duì)象。
②flushInterval屬性:刷新間隔,單位毫秒 默認(rèn)情況是不設(shè)置,也就是沒(méi)有刷新間隔,緩存僅僅調(diào)用語(yǔ)句時(shí)刷新
③size屬性:引用數(shù)目,正整數(shù) 代表緩存最多可以存儲(chǔ)多少個(gè)對(duì)象,太大容易導(dǎo)致內(nèi)存溢出
④readOnly屬性:只讀, true/false
true:只讀緩存;會(huì)給所有調(diào)用者返回緩存對(duì)象的相同實(shí)例。因此這些對(duì)象不能被修改。這提供了 很重 要的性能優(yōu)勢(shì)。
false:讀寫(xiě)緩存;會(huì)返回緩存對(duì)象的拷貝(通過(guò)序列化)。這會(huì)慢一些,但是安全,因此默認(rèn)是 false。
10.4、MyBatis緩存查詢的順序
二級(jí)緩存的范圍大于一級(jí)緩存的范圍,也就是說(shuō),二級(jí)緩存中的數(shù)據(jù)要多于一級(jí)緩存中的。因?yàn)橐粋€(gè)SqlSessionFactory可以對(duì)應(yīng)多個(gè)SqlSession,而一個(gè)一級(jí)緩存只對(duì)應(yīng)一個(gè)SqlSession。但是,SqlSession關(guān)閉之后,一級(jí)緩存中的數(shù)據(jù)才會(huì)寫(xiě)入二級(jí)緩存,所以,當(dāng)SqlSession還沒(méi)有關(guān)閉時(shí),二級(jí)緩存中沒(méi)有一級(jí)緩存中的一些數(shù)據(jù),此時(shí)二級(jí)緩存可能沒(méi)被命中,則查一級(jí),若一級(jí)沒(méi)命中(之前沒(méi)有寫(xiě)入過(guò)一級(jí)緩存),則查數(shù)據(jù)庫(kù)
查詢順序:2 ---> 1 ----> 數(shù)據(jù)庫(kù)
先查詢二級(jí)緩存,因?yàn)槎?jí)緩存中可能會(huì)有其他程序已經(jīng)查出來(lái)的數(shù)據(jù),可以拿來(lái)直接使用。
如果二級(jí)緩存沒(méi)有命中,再查詢一級(jí)緩存
如果一級(jí)緩存也沒(méi)有命中,則查詢數(shù)據(jù)庫(kù)文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-724976.html
SqlSession關(guān)閉之后,一級(jí)緩存中的數(shù)據(jù)才會(huì)寫(xiě)入二級(jí)緩存文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-724976.html
到了這里,關(guān)于MyBatis的緩存,一級(jí)緩存,二級(jí)緩存的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!