暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MyBatis缓存机制

产教Code 2019-07-19
152

         先说缓存,合理使用缓存是优化中最常见的,将从数据库中查询出来的数据放入缓存中,下次使用时不必从数据库查询,而是直接从缓存中读取,避免频繁操作数据库,减轻数据库的压力,同时提高系统性能。


MyBatis系统默认定义了两级缓存


  • 一级缓存和二级缓存

  • 一级缓存是基于PerpetualCache(MyBatis自带)的HashMap本地缓存,作用范围是Session域内    

    • 一级缓存是SqlSession级别的缓存。在操作数据库时需要构造sqlSession对象,在对象中有一个数据结构用于存储缓存数据。不同的sqlSession之间的缓存数据区域是互相不影响的。也就是他只能作用在同一个sqlSession中,不同的sqlSession中的缓存是互相不能读取的

    • 默认情况下,只有一级缓存(SqlSession级别的缓存,也称为本地缓存)开启。一级缓存是一直开启的,SqlSession级别的一个map,数据库同一次会话期间查询到的数据会放在本地缓存中,以后如果需要相同的数据,直接从缓存中拿,没必要再次查询数据库 

    • 一级缓存失效情况:

      • SqlSession不同

      • SqlSession相同,查询条件不同

      • SqlSession相同,再次查询之间执行了增删改操作

      • SqlSession相同,手动清除一级缓存


  • 二级缓存就是global caching,它超出session范围之外,可以被所有SqlSession共享


    • 二级缓存(全局缓存)需要手动开启和配置,它是基于namespace级别的缓存 一个namespace对应一个二级缓存。

    • 工作机制:

      • 一个会话,查询一条数据,这个数据就会被放在当前会话的一级缓存中

      • 如果会话关闭,一级缓存中的数据就会被保存在二级缓存中,新的会话查询信息,就可以参照二级缓存中的内容

      • 不同namespace查看的数据会放在自己对应的map(缓存)中 查出的数据都会被默认先放在一级缓存中,只有会话提交或者关闭之后,一级缓存的数据才会转移到二级缓存中。




接下来我们一起看看怎么使用:


    

1. 开启二级缓存  这是在核心配置文件里打开二级缓存的总开关
   注意:仅仅只是开启,
<setting name="cacheEnabled" value="true" />
false,会关闭二级缓存 不会关闭一级缓存

所有关于setting的设置建议显式配置
  (显式的指定每个我们需要的更改配置的值,即使它是默认的,防止版本更新带来的问题)


2. 去mapper.xml中配置使用二级缓存
    在xml文件中配置<cache></cache>标签
属性:eviction:缓存的回收策略
          flushInterval:缓存刷新间隔(缓存多长时间清除一次,默认不清空) 毫秒为单位
readOnly:缓存是否只读 (true/false) 默认false;
true:只读;MyBatis认为所有从缓存中读取数据库的操作都是只读操作不会修改数据,MyBatis为了加快获取获取速度,直接
会将数据在缓存中的引用交给用户
false:非只读;MyBatis觉得获取的数据可修改,MyBatis会利用序列化&反序列的技术克隆一份新的数据给你
size:缓存存放多少元素
type:指定自定义缓存的全类名
实现Cache接口
3.我们的POJO需要实现序列化接口 Serializable
---------------------






和缓存有关的设置/属性

1.<setting name="cacheEnabled" value="true"  />  
false,会关闭二级缓存 不会关闭一级缓存


2.每个select标签都有useCache="true"
false 不使用缓存 (一级缓存仍然使用,二级缓存关闭)

3.每个增删改标签都有一个flushCache="true"
执行完毕之后清除缓存(一级缓存清空,二级缓存也会清空)
查询标签有一个flushCache="false" 
一旦为true 每次查询都会清空缓存


4.sqlSession.clearCache();
只是清除当前session的一级缓存

5.MyBatis3.3之后有一个设置,
localCacheScope:本地缓存作用域(一级缓存SESSION),
 当前会话的所有数数据都会保存在会话缓存中
STATEMENT:可以禁用一级缓存


其次,为了提高扩展性,MyBatis定义了缓存接口Cache,我们可以通过实现Cache接口来自定义二级缓存。


但是使用二级缓存需要注意的是:


    不能滥用二级缓存,二级缓存也有弊端,从MyBatis默认二级缓存是关闭的就可以看出来。级缓存是建立在namespace下的,如果对表的操作查询可能有牵扯到多个namespace,那么得到的数据就可能是错误的。


例如:

    在数据库我们查询员工工作表、和员工信息表,在查询员工信息的时候我们需要把员工对应的工作也查询出来,那么这个员工信息及工作是被二级缓存缓存在了员工信息对应的命名空间里的,这个时候要是有人来修改员工工作的岗位,是不会影响到员工信息的缓存,那么我们再次查询的时候,拿到的是之前缓存的数据,但是其实这个数据过时的,并不是我们真正需要的数据的。



如有错误,请多多指教🙏🙏

文章转载自产教Code,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论