Mybatis的二级缓存
Mybatis二级缓存是多个SqlSession共享的,其作用域是mapper的同一个namespace(SqlSessionFactory),
不同的sqlSession两次执行相同namespace下的sql语句且向sql中传递参数也相同即最终执行相同的sql语句,
第一次执行完毕会将数据库中查询的数据写到缓存(内存),
第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。
Mybatis默认没有开启二级缓存需要在setting全局参数中配置开启二级缓存。
当二级缓存开启后,同一个命名空间(namespace) 所有的操作语句,都影响着一个共同的 cache,也就是二级缓存被多个 SqlSession 共享,是一个全局的变量。
当开启缓存后,数据的查询执行的流程就是 二级缓存 -> 一级缓存 -> 数据库。
开启二级缓存:
二级缓存默认是不开启的,需要手动开启二级缓存
1、在mybatis全局配置文件, 设置开启二级缓存
在核心配置文件mybatis-config.xml中加入 <setting name="cacheEnabled" value="true"/>
cacheEnabled:对在此配置文件下的所有cache 进行全局性开/关设置。 默认:false
2、在开启二级缓存的Sql映射文件中, 针对于某一个Mapper
<cache/>
3、 对应的实体类必须实现序列化接口
public class User implements Serializable { private static final long serialVersionUID = -3370639937782551454L;
禁用二级缓存
在statement中设置useCache=false可以禁用当前select语句的二级缓存,即每次查询都会发出sql去查询,默认情况是true,即该sql使用二级缓存。
<select id="findOrderListResultMap" resultMap="ordersUserMap" useCache="false">
刷新缓存
在mapper的同一个namespace中,如果有其它insert、update、delete操作数据后需要刷新缓存,如果不执行刷新缓存会出现脏读。
设置statement配置中的flushCache="true" 属性,默认情况下为true即刷新缓存,如果改成false则不会刷新。使用缓存时如果手动修改数据库表中的查询数据会出现脏读。 <insert id="insertUser" parameterType="cn.itcast.mybatis.po.User" flushCache="true">
是否应该使用二级缓存?
- 缓存是以
namespace
为单位的,不同namespace
下的操作互不影响。 - insert,update,delete操作会清空所在
namespace
下的全部缓存。 - 通常使用MyBatis Generator生成的代码中,都是各个表独立的,每个表都有自己的
namespace
。 - 多表操作一定不要使用二级缓存,因为多表操作进行更新操作,一定会产生脏数据。
二级缓存框架: Ehcache, Redis