mybaits提供一级缓存,和二级缓存区别

2021-10-08 14:56:41 浏览数 (1)

mybaits提供一级缓存,和二级缓存区别

  一级缓存是SqlSession级别的缓存。在操作数据库时需要构造 sqlSession对象,在对象中有一个(内存区域)数据结构(HashMap)用于存储缓存数据。不同的sqlSession之间的缓存数据区域(HashMap)是互相不影响的。在同一个sqlSession中两次执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。当一个sqlSession结束后该sqlSession中的一级缓存也就不存在了。Mybatis默认开启一级缓存。但如果开启了二级缓存,那么在关闭sqlsession后,会把该sqlsession一级缓存中的数据添加到namespace的二级缓存中。   对sqlsession执行commit操作,也就意味着用户执行了update、delete等操作,那么数据库中的数据势必会发生变化,如果用户请求数据仍然使用之前内存中的数据,那么将读到脏数据。所以在执行sqlsession操作后,会清除保存数据的HashMap,用户在发起查询请求时就会重新读取数据并放入一级缓存中了。 如何开启二级缓存:

代码语言:javascript复制
1、 在mybatis总配置文件中加入一行设置
<settings>
   <!--开启二级缓存-->
    <setting name="cacheEnabled" value="true"/>
</settings>

2、在需要开启二级缓存的mapper.xml中加入caceh标签
<cache/>

  二级缓存是mapper级别的缓存,按namespace分,如果namespace相同则使用同一个相同的二级缓存区,多个SqlSession去操作数据库得到数据会存在二级缓存区域。注意:即使开启了二级缓存,不同的sqlsession之间的缓存数据也不是想互访就能互访的,必须等到sqlsession关闭了以后,才会把其一级缓存中的数据写入二级缓存。

但是我们并不使用mybaits提供的二级缓存,理由如下:

  1. 缓存是以namespace为单位的,不同namespace下的操作互不影响。例如UserMapper.xml包含一个命名空间,所有针对user表的insert,update,delete操作都在这个命名空间下。假设另外一个XXXMapper.xml对user表的内容进行select查询,并将查询结果二级缓存。然后我们对user表进行insert,update或者delete操作,insert,update,delete操作会清空所在namespace下的全部缓存,但是XXXMapper.xml命名空间下的缓存却没有变化,导致XXXMapper.xml再次查询错误。
  2. 多表操作不能使用缓存。比如我要查询某一个作者的全部文章,作者为一张表,文章为一张表。首先,对不同表的增删改一般放到不同的namespace,原因是:假设我将多表的全部操作放到一个namespace,那么我对任意一张表的增删改都会触发清空这个namespace的全部缓存,导致缓存一直在变,那我就要一直查表,那要缓存也没意义了。然后,假设将查询某一个作者的全部文章这一操作放到作者所在的那个namespace,那么文章表的增删改由于和查询某一个作者的全部文章这一操作不在同一namespace,导致这一操作的二级缓存不变,查询错误。   所以放弃Mybatis二级缓存,在业务层使用可控制的二级缓存代替更好,即服务器上的缓存。推荐使用redis或者ehcache做分布式二级缓存

0 人点赞