MyBatis缓存机制

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:自定义缓存的全类名

posted @ 2018-11-24 22:28  canger  阅读(2497)  评论(0编辑  收藏  举报