# Mybatis 的内置缓存
# 1. Mybatis 一级缓存
# 概述
MyBatis 提供了查询缓存来缓存数据,从而达到提高查询新能的要求。MyBatis 的缓存分为一级缓存和二级缓存。
MyBatis 的一级缓存是 SqlSession 级别的缓存(在操作数据库时需要构造 SqlSession 对象),每个 SqlSession 对象中都有一个 HashMap 对象用于缓存数据,不同的 SqlSession 之间缓存的数据互不影响。
提前说明一下,当 mybatis 与 spring 整合后,如果没有事务,一级缓存是失效的!
原因就是两者结合后,sqlsession 如果发现当前没有事务,那么每执行一个 mapper 方法之后,sqlsession 就被关闭了(
session.close()
)。所以记得给 Service 的方法的脑袋上面加 @Transactional 。
在参数和 SQL 完全相同的情况下,使用同一个 SqlSession 对象调用同一个 Mapper 方法,往往只执行一次 SQL 语句。因为如果没有声明需要刷新缓存并且缓存没有超时,SqlSession 都只会取出当前缓存的数据,而不是执行 SQL 语句。
如果 SqlSession 执行了 DML 操作,并提交数据库,Mybatis 会清空 SqlSession 中的一级缓存,这样做的目的是保证缓存中存储的数据是最新的,避免出现脏读现象。
# 刷新缓存的时机
如果 SqlSession 调用了 close 方法,则一级缓存不可用/销毁。
如果 SqlSession 调用了 clearCache 方法,则一级缓存中缓存的数据被清空。
如果 SqlSession 执行了一个 DML 操作,则一级缓存中缓存的数据被清空。
# 2. Mybatis 二级缓存
二级缓存是 Mapper 级别(也叫 namespace 级别)的缓存,同样使用 HashMap 进行数据存储。
二级缓存是以 namespace 为单位的,不同的 namespace 下的操作相互隔离。
增删改操作会清空 namespace 下的全部缓存。
如果开启了二级缓存,那么在关闭 sqlsession 后,会把该 sqlsession 一级缓存中的数据添加到 namespace 的二级缓存中。
二级缓存比一级缓存作用域更大,多个 sqlsession 可以共用二级缓存,即,二级缓存是跨 sqlsession 的。
例如,关闭一个 sqlsession 之后,打开一个新的 sqlsession,执行同一条 sql 语句,会利用上一次的缓存数据。
mybatis 默认没有开启二级缓存 ,需要在配置中进行配置才能使用。打开二级缓存分为三步:
打开二级缓存总开关
打开需要使用二级缓存的 mapper 的开关。
POJO 序列化
# 打开二级缓存总开关
打开总开关,只需要在 mybatis 总配置文件中加入一行设置
<settings>
<!--开启二级缓存-->
<setting name="cacheEnabled" value="true"/>
</settings>
# 打开需要使用二级缓存的 mapper 的开关。
在需要开启二级缓存的 mapper.xml 中加入 caceh 标签
<cache />
# POJO 序列化
让需要使用二级缓存的 POJO 类实现 Serializable 接口,如
public class Department implements Serializable {
...
}
通过之前三步操作就可以使用二级缓存了。
← 延迟加载 Mybatis-Plus 框架 →