Java——Mybatis二级缓存

Posted 青城博雅教育科技

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java——Mybatis二级缓存相关的知识,希望对你有一定的参考价值。

一、什么是二级缓存

二级缓存是mapper级别的缓存,Mybatis默认是没有开启二级缓存。多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession可以共用二级缓存,也就是说,二级缓存是跨SqlSession的,因此二级缓存的作用范围更大。


UserMapper有一个二级缓存区域(按namespace分),其它mapper也有自己的二级缓存区域(按namespace分)。每一个namespace的mapper都有一个二级缓存区域,两个mapper的namespace如果相同,这两个mapper执行sql查询到数据将存在相同的二级缓存区域中。


 


二、二级缓存原理

不同的sqlsession都要调用mapper下的sql语句发起数据库请求。 


第一次调用mapper下的SQL去查询用户信息。查询到的信息会存到该mapper对应的二级缓存区域内。


第二次调用相同namespace下的mapper映射文件中相同的SQL去查询用户信息。会去对应的二级缓存内取结果。


如果调用相同namespace下的mapper映射文件中的增删改SQL,并执行了commit操作。此时会清空该namespace下的二级缓存。


sqlsession对象销毁mapper中的二级缓存数据仍然存在。


 


三、开启二级缓存

1、  在核心配置文件SqlMapConfig.xml中加入以下内容(开启二级缓存总开关):


cacheEnabled设置为 true



Java——Mybatis二级缓存

 


 


2、在映射文件中,加入以下内容,开启二级缓存:


Java——Mybatis二级缓存


 


3、实现序列化


由于二级缓存的数据不一定都是存储到内存中,它的存储介质多种多样,所以需要给缓存的对象执行序列化。


如果该类存在父类,那么父类也要实现序列化。


Java——Mybatis二级缓存


 


禁用二级缓存


该statement中设置userCache=false可以禁用当前select语句的二级缓存,即每次查询都是去数据库中查询,默认情况下是true,即该statement使用二级缓存。


 


刷新二级缓存



 

四、如何解决一级缓存中Spring和Mybatis中sqlSession关闭的问题?

Spring和MyBatis整合时, 每次查询之后都要进行关闭sqlSession,关闭之后数据被清空。所以spring整合之后,如果没有事务,一级缓存是没有意义的。而如果开启二级缓存的话,关闭sqlsession后,会把该sqlsession一级缓存中的数据添加到namespace的二级缓存中。这样,缓存在sqlsession关闭之后依然存在。


 

四、问题

二级缓存是建立在同一个namespace下的,如果对表的操作查询可能有多个namespace,那么得到的数据就是错误的。


举个例子:


订单和订单详情,orderMapper、orderDetailMapper。在查询订单详情时我们需要把订单信息也查询出来,那么这个订单详情的信息被二级缓存在orderDetailMapper的namespace中,这个时候有人要修改订单的基本信息,那就是在orderMapper的namespace下修改,他是不会影响到orderDetailMapper的缓存的,那么你再次查找订单详情时,拿到的是缓存的数据,这个数据其实已经是过时的。


根据以上,想要使用二级缓存时需要想好两个问题:


对该表的操作与查询都在同一个namespace下,其他的namespace如果有操作,就会发生数据的脏读。

对关联表的查询,关联的所有表的操作都必须在同一个namespace。


以上是关于Java——Mybatis二级缓存的主要内容,如果未能解决你的问题,请参考以下文章

MyBatis二级缓存带来的问题

Mybatis一级缓存与二级缓存的区别你知道吗

Mybatis一级缓存与二级缓存的区别你知道吗

mybatis二级缓存默认开启吗?

16-二级缓存

mybatis二级缓存原理