mybatis缓存

…衆ロ難τιáo~ 提交于 2020-01-15 07:53:16

一级缓存:

一级缓存在mybatis是默认开启的;
一级缓存的作用范围只在会话级别,即会话死亡,缓存也会跟着清空

缓存清空的时机:

执行添加,修改,删除,提交,关闭会话等操作会情况SQLSession张红的一级缓存数据;

:当没有配置连接池的时候,同一个会话里面查询两次才会使用一级缓存,这样就显得比较鸡肋
但是当我们配置了线程池以后,连接池中有一定数量的常驻会话,这些会话是会循环使用不会关闭的
所以会有第一的几率命中一级缓存,在并发高的情况下,也能减轻很多负担

二级缓存:

二级缓存是默认关闭
二级换在整个会话级别都是有效的(也就是所有的session/namespace共享的),只要会话工厂不死,二级缓存就在;

二级缓存的使用:
  1. 二级缓存在使用前要开启,需要在核心配置文件的settings标签下开启;
    <settings>
        <!--开启懒加载-->
        <setting name="lazyLoadingEnabled" value="true"/>
        <!--开启缓存-->
        <setting name="cacheEnabled" value="true"/>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
  1. 二级缓存缓存对象必须实现序列化接口:因为二级缓存他有可能会存到本地文件中
  2. 核心配置文件中配置了cacheEnable还是不行的,需要在使用缓存的mapper.xml中添加标签:
<cache/>

标签或者在mapperr接口中添加注解:

@CacheNamespace

二级缓存的底层原理:

二级缓存底层是使用map集合存储键值对,sql语句为键,查询的结果为值,缓存命中后直接通过键取值,所有他的效率非常高;

mybatis缓存机制

二级缓存清除时机:

执行增删改的时候会清除缓存

官方文档:

二级缓存是事务性的。这意味着,当 SqlSession 完成并提交时,或是完成并回滚,但没有执行 flushCache=true 的 insert/delete/update 语句时,缓存会获得更新。
效果如下:

  1. 映射语句文件中的所有 select 语句的结果将会被缓存。
  2. 映射语句文件中的所有 insert、update 和 delete 语句会刷新缓存。
  3. 缓存会使用最近最少使用算法(LRU, Least Recently Used)算法来清除不需要的缓存。
  4. 缓存不会定时进行刷新(也就是说,没有刷新间隔)。
  5. 缓存会保存列表或对象(无论查询方法返回哪种)的 1024 个引用。
  6. 缓存会被视为读/写缓存,这意味着获取到的对象并不是共享的,可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。

注意:
在另外一namespace中修改了当前namespace的数据时,当前namespace不能识别,下次读取的时候会直接读取缓存,这样的就会读出脏数据,
但你可能会想要在多个命名空间中共享相同的缓存配置和实例。要实现这种需求,你可以使用 cache-ref 元素来引用另一个缓存。

<cache-ref namespace="com.someone.application.data.SomeMapper"/>

在没有关联查询的时候,数据会更新到二级缓存中,再次读取的时候直接命中缓存
但是当存在二级缓存时,会再次到数据库查询出最新的数据
配置cache-ref-01
配置cache-ref-02
配置了以后两者共享缓存。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!