MyBatis的二级缓存
二级缓存:是MyBatis中SqlSessionFactory对象的缓存(默认是关闭的),MyBatis 一级缓存最大的共享范围就是一个SqlSession内部,那么如果多个 SqlSession 需要共享缓存,则需要开启二级缓存,开启二级缓存后,由同一个SqlSessionFactory对象创建的SqlSession共享其缓存。
开启二级缓存后,进入一级缓存的查询流程前,先在CachingExecutor 进行二级缓存的查询。
二级缓存的使用步骤
第一步:让Mybatis框架支持二级缓存,在sqlMapContext.xml中配置如下代码
<!-- 配置开启延迟加载-->
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="lazyLoadTriggerMethods" value="clone"/>
<!-- 开启二级缓存配置1-->
<setting name="cacheEnabled" value="true"/>
</settings>
第二步:在映射文件中配置
<!--配置2级缓存开启标签-->
<cache></cache>
第三步:让当前的操作支持二级缓存(在select标签中配置)
<select id="findById" parameterType="int" resultType="student" useCache="true">
select * from tb_stu where id = #{id}
</select>
当开启缓存后,数据的查询执行的流程就是 二级缓存 -> 一级缓存 -> 数据库。
二级缓存中存储的并不是对象,而是数据,谁需要,则封装成对象,导致每次获取二级缓存中的对象都是不一致的
具体分析:
分析一
分析二
分析三
分析四
(大佬写的有点看不懂,留着慢慢看。)
一般mybatis通过oscache来实现他的二级缓存,然而这种方式存在如下几个问题:
1:oscache可以用来缓存页面和数据对象,但数据存放在内存中,项目多实例环境下无法解决缓存更新问题(数据同步)。
2:oscache可以将数据通过io写到硬盘保持数据一致性,但此举会浪费资源(硬盘小,那就换个大的)
解决方案:使用redis
使用redis实现一套mybatis二级缓存插件,将数据从内存转移到redis中,各个项目访问唯一一个redis实例,这样就保证缓存的变化都会被所有项目感知,并使用最新的缓存数据;redis的高性能也保证了缓存数据的读取熟读。