MyBatis 提供了一級緩存和二級緩存的支持。
一級緩存
一級緩存是基於PerpetualCache 的 HashMap本地緩存;
一級緩存的作用域是SqlSession,即不同的SqlSession使用不同的緩存空間;
一級緩存的開啟和關閉
- 一級緩存是默認開啟的;
- 關閉一級緩存只需要在settings中設置localCacheScope為STATEMENT
導致一級緩存不命中的原因
-
一級緩存關閉;
-
一級緩存開啟,但是使用了不同的SqlSession進行查詢;
-
使用相同的SqlSession,但是查詢條件發生了變化;
-
使用了相同的查詢條件,但是兩次查詢之間SqlSession執行了commit、clearCache或close(關閉之后查詢會報錯)操作;
- 使用了相同的查詢條件,但是兩次查詢之間SqlSession執行了insert、update或delete操作,此時無論三種標簽的 flushCache 屬性是否為 false,都會清空 sqlSession的緩存;
-
select標簽的flushCache屬性為true
清空一級緩存的操作
-
SqlSession調用commit方法;
-
SqlSession調用clearCache方法;
-
select標簽的flushCache屬性為true;
-
SqlSession執行了insert、update或delete操作,此時無論三種標簽的 flushCache 屬性是否為 false;
二級緩存
二級緩存默認也是采用 PerpetualCache,HashMap存儲;
二級緩存的存儲作用域為 Mapper(確切說是Namespace),即一個Mapper執行了insert、update或delete操作,不影響另外一個Mapper(不同namespace);
二級緩存可自定義存儲實現,如 Ehcache、redis;
二級緩存開啟后,需要對應的java Bean實現
二級緩存的開啟和關閉
- settings中可設置 cachaEnable為true或false,該屬性是二級緩存的總開關,如果關閉,則所有mapper的二級緩存均不生效;
- 在cachaEnable為true的情況下,在mapper文件中添加<cache/>標簽即可開啟二級緩存,如果沒有該標簽,則二級緩存不生效;
二級緩存不命中的情況
-
二級緩存未開啟;
-
第一次查詢之后,SqlSession未執行commit或close操作,導致該查詢的二級緩存還未生效;
-
兩次查詢之間,mapper(同一命名空間)執行了insert、update或delete操作;
-
insert、update或delete標簽的flushCache屬性默認為true,此時會清除一級緩存和二級緩存;
-
insert、update或delete標簽的flushCache屬性為false時,不會清除二級緩存,依然清空一級緩存;
-
- select標簽的flushCache屬性(默認false)的值為true;
cache標簽屬性
-
eviction:緩存回收策略:flushInterval:緩存多長時間清空一次,默認不清空,單位毫秒 ms
- LRU——最少使用的,移除最長時間不適用的對象;
- FIFO——先進先出
- WEAK——弱引用,更積極的移除基於垃圾回收器狀態和弱引用規則的對象
- SOFT——軟引用,更積極的移除基於垃圾回收器狀態和弱引用規則的對象
- flushInterval:緩存多久清空一次,默認不清空,時間毫秒 ms
-
readOnly:緩存是否只讀
-
size:緩存覺存放元素個數,默認1024
-
type:自定義緩存的全類名
