Mybatis的缓存分为一级缓存、二级缓存
一级缓存范围只在controller里,并且需要同一个sqlsession才会影响缓存内容
二级缓存范围在项目里所有的controller中都有效
一级缓存
/**
* 一级缓存 相同的SqlSession
*/
@Test
public void testCacheOneSameSession() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
try {
SysUserMapper sysUserMapper = sqlSession.getMapper(SysUserMapper.class);
System.out.println("第一次查询:");
List<SysUser> userList1 = sysUserMapper.selectByCondition("admin");
for (SysUser user : userList1) {
System.out.println(user);
}
System.out.println("第二次查询:");
List<SysUser> userList2 = sysUserMapper.selectByCondition("admin");
for (SysUser user : userList2) {
System.out.println(user);在日志和输出中:
第一次查询发送了 SQL 语句, 后返回了结果;
第二次查询没有发送 SQL 语句, 直接从缓存中获取了结果。
第一次的对象和第二次的对象是相同的。
//判断是相同
System.out.println("userList1 == userList2 "+(userList1 == userList2 ));
} finally {
sqlSession1.close();
sqlSession2.close();
}
}
清空缓存
/**
* 一级缓存 清空缓存(Java代码)
*/
@Test
public void testCacheOneCleanCacheJavaCode() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
try {
SysUserMapper sysUserMapper = sqlSession.getMapper(SysUserMapper.class);
System.out.println("第一次查询:");
List<SysUser> userList1 = sysUserMapper.selectByCondition("admin");
for (SysUser user : userList1) {
System.out.println(user);
}
//清空缓存
System.out.println("清空缓存");
sqlSession.clearCache();
System.out.println("第二次查询:");
List<SysUser> userList2 = sysUserMapper.selectByCondition("admin");两次都发送了 SQL 语句, 同时两个对象不相同。
9.1.3.2、Mapper.xml配置方式
在SysUserMapper.xml的selectByCondition方法上添加 flushCache="true" 属性
for (SysUser user : userList2) {
System.out.println(user);
}
//判断是相同
System.out.println("userList1 == userList2 "+(userList1 == userList2 ));
} finally {
sqlSession.close();
}
}
二级缓存
/**
* 二级缓存 不同的SqlSession
*/
@Test
public void testCacheTwoDifferentSession() {
SqlSession sqlSession1 = MybatisUtils.getSqlSession();
SysUserMapper sysUserMapper = sqlSession1.getMapper(SysUserMapper.class);
System.out.println("sqlSession1查询:");
List<SysUser> userList1 = sysUserMapper.selectByCondition("admin");9.3、缓存使用注意事项
1. 由于在更新时会刷新缓存, 因此需要注意使用场合:查询频率很高, 更新频率很低时使用, 即经
常使用 select, 相对较少使用insert, update,delete。
2. 缓存是以 namespace 为单位的,不同 namespace 下的操作互不影响。但刷新缓存是刷新整个
namespace 的缓存, 也就是你 insert, update,delete 了一个, 则整个缓存都刷新了。
3. 最好在 「只有单表操作」 的表的 namespace 使用缓存, 而且对该表的操作都在这个
namespace 中。 否则可能会出现数据不一致的情况。
for (SysUser user : userList1) {
System.out.println(user);
}
sqlSession1.close();
SqlSession sqlSession2 = MybatisUtils.getSqlSession();
SysUserMapper sysUserMapper2 = sqlSession2.getMapper(SysUserMapper.class);
System.out.println("sqlSession2查询:");
List<SysUser> userList2 = sysUserMapper2.selectByCondition("admin");
for (SysUser user : userList2) {
System.out.println(user);
}
sqlSession2.close();
//判断是否相同
System.out.println("userList1 == userList2 "+(userList1 == userList2 ));
}