一级缓存
- Mybatis的一级缓存存放在SqlSession的生命周期,在同一个SqlSession中查询时,Mybatis会把执行的方法和参数经过算法生成缓存的键值,将键值和查询结果存入一个Map对象中。
- 若是同一个SqlSession中执行的方法和参数彻底一致,那么经过算法会生成相同的键值,当Map缓存对象中已经存在改键值时,则会返回缓存中的对象。(一个SqlSession连续两次查询 获得的是同一个java对象)
- 任何的insert update delete操做都会清空一级缓存(增删改任何记录都会清空当前SqlSession的缓存)。
Spring整合Mybatis的时候一级缓存的问题:java
在未开启事物的状况之下,每次查询,spring都会关闭旧的sqlSession而建立新的sqlSession,所以此时的一级缓存是没有启做用的redis
在开启事物的状况之下,spring使用threadLocal获取当前资源绑定同一个sqlSession,所以此时一级缓存是有效的算法
Spring结合Mybatis一级缓存失效的问题spring
二级缓存
Mybatis二级缓存能够理解为存在SqlSessionFactory的生命周期sql
开启二级缓存:数据库
1.在mybatis-config.xml添加以下代码缓存
<settings> <setting name="cacheEnable" value="true"></setting> </settings>
2.在对应的XXXMapper.xml的namespace下添加<cache/>元素mybatis
二级缓存特色:并发
SqlSession1调用getMapper获取对象user1app
SqlSession1调用getMapper获取对象user2
user1和user2是同一个实例(原理同一级缓存)
若是二级配置可读写的缓存 <cache readOnly="false"/>,不一样SqlSession之间经过序列化和反序列化来保证经过缓存获取数据。
SqlSession2调用getMapper获取对象user1_
SqlSession2调用getMapper获取对象user2_
user1_和user2_就是反序列化获得的结果 是不一样的实例
Redis缓存一致性
Mybatis默认提供的缓存是基于Map实现的内存缓存,已经能够基本知足应用。但当须要缓存大量数据的时候可使用Redis缓存数据库来保存Mybatis的二级缓存数据。
但MySQL和Redis是两个事物,很差作强一致性。
简单点:能够延时双删+过时时间保证最终一致性。
双删的缘由是防止并发状况下 update_db的过程当中 其余事物发现redis缓存是空 从新赋予了Redis的值 此时若是赋值 是错误的数据
第二次延时删除的缘由是要考虑MySQL数据库主从同步的耗时(若是当即删除 有别的线程从MySQL的从库查到的数据放到Redis中 此时的从库多是没同步的错误数据)
rm_redis update_db sleep xxx ms rm_redis