MyBatis(一)-----MyBatis中的二级缓存

一.二级缓存的介绍

1)二级缓存是用来解决一级缓存不能跨会话共享的问题的,范围是namespace级别的,可以被多个SqlSession共享(只要是同一个接口里面的相同方法,都可以共享),生命周期和应用同步

二.面试题

1.如果开启了二级缓存,二级缓存应该是工作在一级缓存之前,还是在一级缓存之后呢?二级缓存是在哪里维护的呢? 答:

作为一个作用范围更广的缓存,它肯定是在SqlSession的外层,否则不可能被多个SqlSession共享。而一级缓存是在SqlSession内部的,所以第一个问题,肯定是工作在一级缓存之前,也就是只有取不到二级缓存的情况下才到一个会话中去取一级缓存。

2.二级缓存放在哪个对象中维护呢?

要跨会话共享的话,SqlSession本身和它里面的BaseExecutor已经满足不了需求了,那我们应该在BaseExecutor之外创建一个对象。实际上MyBatis用了一个装饰器的类来维护,就是CachingExecutor。如果启用了二级缓存,MyBatis在创建Executor对象的时候会对Executor进行装饰,CachingExecutor对于查询请求,会判断二级缓存是否有缓存结果,如果有就直接返回,如果没有委派交给真正的查询器Executor实现类,比如SimpleExecutor来执行查询,再走到一级缓存的流程。最后会把结果缓存起来,并且返回给用户。

在这里插入图片描述

3.二级缓存的开启方式?

第一步:在mybatis-config.xml中配置了(可以不配置,默认是true):

在这里插入图片描述
只要没有显式地设置 cacheEnabled=false,都会用 CachingExecutor 装饰基本的执行器
第二步:在Mapper.xml 中配置标签:
Mapper.xml配置了之后,select()会被缓存。update()、delete()、会刷新缓存。

4.如果cacheEnabled=true,Mapper.xml没有配置标签,还有二级缓存吗?还会出现CachingExecutor包装对象吗?

只要cacheEnabled=true基本执行器就会被装饰。有没有配置,决定了在启动的时候会不会创建这个mapper的Cache对象,最终会影响到CachingExecutor query方法里面的判断:
if(cache!=null){

5.二级缓存的关闭?

我们可以在单个StatementID上显式关闭二级缓存(默认是true):

在这里插入图片描述

6.为什么事务不提交,二级缓存不存在

在这里插入图片描述
因为二级缓存使用TransactionalCacheManager(TCM)来管理,最后又调用了TransactionalCache的getObject()、putObject和commit()方法,TransactionalCache 里面又持有了真正的Cache对象,比如是经过层层装饰的PerpetualCache。在putObject的时候,只是添加到了entriesToAddOnCommit里面,只有它的commit()方法被调用的时候才会调用flushPendingEntries()真正写入缓存。它就是在DefaultSqlSession调用commit()的时候被调用的。
*

7.什么情况下有必要去开启二级缓存

1、因为所有的增删改都会刷新二级缓存,导致二级缓存失效,所以适合在查询为主的应用中使用,比如历史交易、历史订单的查询。否则缓存就失去了意义。

2、如果多个namespace中有针对于同一个表的操作,比如Blog表,如果在一个namespace中刷新了缓存,另一个namespace中没有刷新,就会出现读到脏数据的情况。所以,推荐在一个Mapper里面只操作单表的情况使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值