前言
缓存的具体执行过程可以关注
3、MyBatis中关于mapper的执行过程
一级缓存
代码位置
org.apache.ibatis.executor.BaseExecutor#query();
// 一级缓存的存储对象
protected PerpetualCache localCache
介绍
1、一级缓存默认开启,所以在参数和SQL完全一样的情况下,我们使用同一个SqlSession对象调用一个Mapper方法,往往只执行一次SQL,因为使用SelSession第一次查询后,MyBatis会将其放在缓存中,以后再查询的时候,如果没有声明需要刷新,并且缓存没有超时的情况下,SqlSession都会取出当前缓存的数据,而不会再次发送SQL到数据库。
注意:MyBatis在开启一个数据库会话时,会 创建一个新的SqlSession对象。commit之后,缓存消失
Key 的组成
一级缓存的key主要是 statementId+sql语句+参数+值+DB类型 )
二级缓存也是这个key
关闭一级缓存
- 全局设置 mybatis.configuration.local-cache-scope=statement ,则查询之后即便放入了一级缓存,但存放完立马就给清了,下一次还是要查数据库;原因如图中截图部分。
statement 设置 flushCache=”true” ,则查询之前先清空一级缓存,还是得查数据库;
<select id="queryById" resultMap="baseMap" flushCache="true">
select * from user where id = ${id}
</select>
设置随机数,如果随机数的上限足够大,那随机到相同数的概率就足够低,也能类似的看成不同的数据库请求,那缓存的 key 都不一样,自然就不会匹配到缓存。
- 例如 两次查询分别用 (int)Math.random()1000 (int)Math.random()10000 ;where #{randomString}=#{randomString}
清空一级缓存
更新的时候,不管更新什么东西,都会清空sqlSession下的所有缓存。
二级缓存
代码位置
org.apache.ibatis.executor.CachingExecutor#query()// 二级缓存的存储对象
private final TransactionalCacheManager tcm = new TransactionalCacheManager();
介绍
SqlSessionFactory层面上的二级缓存默认是不开启的,二级缓存的开启需要进行配置,实现二级缓存的时候,MyBatis要求返回的POJO必须是可序列化的。 也就是要求实现Serializable接口,配置方法很简单,只需要在映射XML文件配置就可以开启缓存了开启二级缓存
XML文件配置就可以开启缓存
在select标签内使用 useCache=true。
- 例如 两次查询分别用 (int)Math.random()1000 (int)Math.random()10000 ;where #{randomString}=#{randomString}