Mybatis的二级缓存

jimgreatly 2020-06-03

Mybatis二级缓存是多个SqlSession共享的,其作用域是mapper的同一个namespace(SqlSessionFactory)

不同的sqlSession两次执行相同namespace下的sql语句且向sql中传递参数也相同即最终执行相同的sql语句,

第一次执行完毕会将数据库中查询的数据写到缓存(内存),

第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。

Mybatis默认没有开启二级缓存需要在setting全局参数中配置开启二级缓存。

Mybatis的二级缓存

 当二级缓存开启后,同一个命名空间(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">

是否应该使用二级缓存?

  1. 缓存是以namespace为单位的,不同namespace下的操作互不影响。
  2. insert,update,delete操作会清空所在namespace下的全部缓存。
  3. 通常使用MyBatis Generator生成的代码中,都是各个表独立的,每个表都有自己的namespace
  4. 多表操作一定不要使用二级缓存,因为多表操作进行更新操作,一定会产生脏数据。

二级缓存框架:  Ehcache,  Redis

相关推荐