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