mybatis 一级缓存和二级缓存

12 阅读1分钟

概念

  • 一级缓存

一级缓存是 SqlSession 级别的缓存。在操作数据库时,同一个 SqlSession 内的两次相同查询会调用缓存中的数据,而不会再次查询数据库。当执行 insert、update、delete 等更新数据库的操作时,一级缓存会被清空。

  • 二级缓存

二级缓存是 mapper 级别的缓存,多个 SqlSession 可以共享。二级缓存的作用范围是一个 namespace,不同的 SqlSession 可以共享。当执行 insert、update、delete 等更新数据库的操作时,所在的 namespace 下的二级缓存会被清空。

使用方式

  • 一级缓存默认是开启的
  • 二级缓存默认关闭,开启二级缓存如下设置
mybatis-config.xml中
<settings>
    <!-- 开启二级缓存 -->
    <setting name="cacheEnabled" value="true"/>
</settings>

xxMapper.xml文件中
<mapper namespace="YourMapperNamespace">
    <!-- 开启二级缓存 -->
    <cache/>
    <!-- 其他的 select, insert, update, delete 等语句 -->
</mapper>

一级缓存清除,清除的是sqlSession1的范围

  • sqlSession1.commit();
  • sqlSession1.close();
  • sqlSession1.insert\update\delete

二级缓存清除,清除的是namespace的范围(可以说是mapper范围,没有在多个mapper文件中使用同一个namespace)

  • sqlSession1.commit();
  • sqlSession1.close();
  • mapper1.insert\update\delete 清空mapper1下的二级缓存

缓存命中和清除示列

// 获取 SqlSession
SqlSession sqlSession1 = sqlSessionFactory.openSession();
SqlSession sqlSession2 = sqlSessionFactory.openSession();
 
// 获取 Mapper 接口实例
YourMapper mapper1 = sqlSession1.getMapper(YourMapper.class);
YourMapper mapper2 = sqlSession2.getMapper(YourMapper.class);
 
// 执行查询,使用一级缓存
mapper1.selectById(1);
mapper1.selectById(1); // 这次查询会使用一级缓存
 
// 提交或关闭 SqlSession 会清空一级缓存
sqlSession1.commit();
sqlSession1.close();
 
// 执行更新操作,会清空 namespace 下的二级缓存
mapper2.updateData(data);
 
// 执行查询,使用二级缓存
mapper2.selectById(1);
mapper1.selectById(1); // 这次查询会使用二级缓存
 
// 提交或关闭 SqlSession 会清空二级缓存
sqlSession2.commit();
sqlSession2.close();

mybatis 中sqlSession、connection、mapper的关系

  • sqlSession的创建是跟线程绑定的,每个线程有个ThreadLocal来保存sqlSession
  • connection 是sqlSession执行时从连接池中获取的