1.緩存介紹
?Mybatis提供查詢緩存,如果緩存中有數(shù)據(jù)就不用從數(shù)據(jù)庫中獲取,用于減輕數(shù)據(jù)壓力,提高系統(tǒng)性能。
?Mybatis的查詢緩存總共有兩級,我們稱之為一級緩存和二級緩存,如圖:?

一級緩存是SqlSession級別的緩存。在操作數(shù)據(jù)庫時需要構(gòu)造 sqlSession對象,在對象中有一個數(shù)據(jù)結(jié)構(gòu)(HashMap)用于存儲緩存數(shù)據(jù)。不同的sqlSession之間的緩存數(shù)據(jù)區(qū)域(HashMap)是互相不影響的。
二級緩存是Mapper(namespace)級別的緩存。多個SqlSession去操作同一個Mapper的sql語句,多個SqlSession可以共用二級緩存,二級緩存是跨SqlSession的。
2.一級緩存
? ? (1)?Mybatis默認開啟了一級緩存
? ? (2)原理圖
? ??

第一次發(fā)起查詢用戶id為1的用戶信息,先去找緩存中是否有id為1的用戶信息,如果沒有,從數(shù)據(jù)庫查詢用戶信息,將查詢到的用戶信息存儲到一級緩存中。
如果中間sqlSession去執(zhí)行commit操作(執(zhí)行插入、更新、刪除),清空SqlSession中的一級緩存,這樣做的目的為了讓緩存中存儲的是最新的信息,避免臟讀。
第二次發(fā)起查詢用戶id為1的用戶信息,先去找緩存中是否有id為1的用戶信息,緩存中有,直接從緩存中獲取用戶信息。
3.二級緩存
? ? (1) 二級緩存是namespace級別的,默認不開啟
? ? (2) 開啟步驟
? ? ? ? 1)?<settings>
? ? ? ? <setting?"cacheEnabled"value="true"/>
????????</settings>
? ? ? ? 2) 在mapper.xml中 加入標簽 <cache/> 核心參數(shù)可不設(shè)置 使用默認參數(shù)
? ??????<!--開啟本mapper下的namespace的二級緩存,默認使用的是mybatis提供的PerpetualCache -->
? ? (3) 原理圖

? ??
第一次調(diào)用mapper下的SQL去查詢用戶信息。查詢到的信息會存到該mapper對應(yīng)的二級緩存區(qū)域內(nèi)。
第二次調(diào)用相同namespace下的mapper映射文件中相同的SQL去查詢用戶信息。會去對應(yīng)的二級緩存內(nèi)取結(jié)果。
如果調(diào)用相同namespace下的mapper映射文件中的增刪改SQL,并執(zhí)行了commit操作。此時會清空該namespace下的二級緩存。
禁用二級緩存
默認二級緩存的粒度是Mapper級別的,但是如果在同一個Mapper文件中某個查詢不想使用二級緩存的話,就需要對緩存的控制粒度更細。
在select標簽中設(shè)置useCache=false,可以禁用當前select語句的二級緩存,即每次查詢都是去數(shù)據(jù)庫中查詢,默認情況下是true,即該statement使用二級緩存。
<selectid="findUserById"parameterType="int"
?????????????????? resultType="com.kkb.mybatis.po.User"useCache="true">
???????? SELECT * FROM user WHERE id = #{id}
</select>
刷新二級緩存
通過flushCache屬性,可以控制select、insert、update、delete標簽是否屬性二級緩存
默認設(shè)置
?????? *默認情況下如果是select語句,那么flushCache是false。
?????? *如果是insert、update、delete語句,那么flushCache是true。
默認配置解讀
?????? *如果查詢語句設(shè)置成true,那么每次查詢都是去數(shù)據(jù)庫查詢,即意味著該查詢的二級緩存失效。
?????? *如果增刪改語句設(shè)置成false,即使用二級緩存,那么如果在數(shù)據(jù)庫中修改了數(shù)據(jù),而緩存數(shù)據(jù)還是原來的,這個時候就會出現(xiàn)臟讀。
flushCache設(shè)置如下:
<selectid="findUserById"parameterType="int"
?????????????????? resultType="com.kkb.mybatis.po.User"useCache="true"flushCache="true">
?????????????????? SELECT * FROM user WHERE id =#{id}
</select>