一篇读懂--mybatis的缓存
一篇讀懂–mybatis的緩存
MyBatis的緩存指的是緩存查詢結(jié)果,當(dāng)以后使用相同的sql語句、傳入相同的參數(shù)進(jìn)行查詢時(shí),可直接從mybatis本地緩存中獲取查詢結(jié)果,而不必查詢數(shù)據(jù)庫。
mybatis的緩存包括一級(jí)緩存、二級(jí)緩存,一級(jí)緩存默認(rèn)是開啟的,二級(jí)緩存默認(rèn)是關(guān)閉的。
一級(jí)緩存:
SqlSession級(jí)別:在SqlSession中有一個(gè)Map,key是由sql語句、參數(shù)等信息組成的唯一值,value是查詢出來的結(jié)果對(duì)象。
好處: 減小數(shù)據(jù)庫壓力
如何失效 :只要此sqlSession調(diào)用了、、這些會(huì)修改數(shù)據(jù)庫的元素,就會(huì)清空此sqlSession的一級(jí)緩存,不管有沒有使用commit()提交。
舉例:
第一次查詢時(shí),就將查詢結(jié)果放到一級(jí)緩存中。
如果后續(xù)使用的sql語句相同、傳入的實(shí)參也相同,則結(jié)果對(duì)象也會(huì)相同,直接從一級(jí)緩存中獲取結(jié)果對(duì)象,不再查詢數(shù)據(jù)庫。
如果此sqlSession調(diào)用了commit()方法,會(huì)自動(dòng)清空此sqlSession的一級(jí)緩存。
因?yàn)槭褂胏ommit(),會(huì)將修改提交到數(shù)據(jù)庫,下一次相同的查詢,查詢結(jié)果可能變了,之前的一級(jí)緩存不能再用,所以會(huì)自動(dòng)清空。
下面用spring整合mybatis來測試一下mybatis的一級(jí)緩存:
1、下面是service層實(shí)現(xiàn), 可以看到,我兩次查詢了同一個(gè)數(shù)據(jù),理論上由于mybatis中默認(rèn)開啟一級(jí)緩存, 那么第二次肯定時(shí)要從緩存中獲取,而不是創(chuàng)建SqlSession對(duì)象重新從數(shù)據(jù)庫獲取:
從日志信息可以很明顯的看到,代碼中的兩次查詢構(gòu)建了兩個(gè)SqlSession對(duì)象,也就是說第二次查詢并沒有從前一次的SqlSession緩存中獲取,而是自己新建一個(gè)SQLSession對(duì)象,重新查詢;這樣看來,一級(jí)緩存好像失效了?
這是為什么呢?因?yàn)槲覀儧]有加@Transaction注解
spring 中 結(jié)合 mybatis中,默認(rèn)情況下,數(shù)據(jù)庫處于自動(dòng)提交模式,每一條sql語句處于一個(gè)單獨(dú)的事務(wù)中,語句執(zhí)行完畢時(shí),如果執(zhí)行成功則隱式提交事務(wù)。而mybatis的一級(jí)緩存在這種情況下是無效的,想要一級(jí)緩存起作用,則要開啟事務(wù):
開啟事務(wù): spring使用ThreadLocal獲取當(dāng)前資源綁定同一個(gè)SQLSession
未開啟事務(wù):每次查詢,spring關(guān)閉舊的SslSession,創(chuàng)建一個(gè)新的Sqlsession對(duì)象,一級(jí)緩存補(bǔ)氣作用
還有一種特殊情況,也會(huì)調(diào)用到緩存:
ProcessDef list = processMapper.selectByPrimaryKey(5L);list.setCode("123");ProcessDef list1 = processMapper.selectByPrimaryKey(5L);(注意,上面這個(gè)方法要加上@Transaction注解)
像上面這種情況,有時(shí)候在代碼中也會(huì)出現(xiàn),然后你就會(huì)找bug找半天都找不出問題;
結(jié)果是:list1的結(jié)果中的Code字段是“123”,而不是數(shù)據(jù)庫中的那個(gè)字段!是不是不可思議,你可以自己在本地試試,事實(shí)就是如此。
原因是什么呢? 上面第一次查詢直接去數(shù)據(jù)庫查,這個(gè)可以理解, list.setCode(“123”);之后,第一次查詢出來的緩存就已經(jīng)變了,其中code字段就變成123了,所以這也是list1中code字段為123的原因!(這種情況大家要留意一下,搞了我半天的時(shí)間去找bug)
二級(jí)緩存:
mapper級(jí)別,同一個(gè)namespace下的mapper,有一個(gè)Map。
不使用二級(jí)緩存,會(huì)執(zhí)行2次查詢。
總結(jié)
以上是生活随笔為你收集整理的一篇读懂--mybatis的缓存的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 图之遍历--广度优先遍历
- 下一篇: Mybatis从入门到精通下篇