mybatis学习及原理解析(三)
程序员文章站
2022-07-13 10:08:26
...
关于mybatis的二级缓存
第一次测试
@Test
public void firstLevelCache() {
//第一次查询id为1的用户
User user1 = userMapper.findUserById(1);
User user2 = userMapper.findUserById(1);
System.out.println(user1 == user2);
}
@Test
public void secondLevelCache() {
SqlSession sqlSession1 = sqlSessionFactory.openSession();
SqlSession sqlSession2 = sqlSessionFactory.openSession();
SqlSession sqlSession3 = sqlSessionFactory.openSession();
IUserMapper mapper1 = sqlSession1.getMapper(IUserMapper.class);
IUserMapper mapper2 = sqlSession2.getMapper(IUserMapper.class);
IUserMapper mapper3 = sqlSession3.getMapper(IUserMapper.class);
User user1 = mapper1.findUserById(1);
sqlSession1.close();
User user2 = mapper2.findUserById(1);
User user3 = mapper3.findUserById(1);
System.out.println(user1 == user2);
}
写了两个测试方法,
- 第一个测试方法用同一个sqlSession执行两次findUserById,发现,第一次调用,执行了sql语句,第二次没有执行sql语句,打印结果为true
- 第二个测试方法测试二级缓存,两次调用findUserById,第一次调用,执行了sql语句,第二次没有执行sql语句,打印结果为flase,注:二级缓存实体类需要实现序列化接口
原因
一级缓存保存的是查询的对象
二级缓存只保存查询出的值
第二次测试
@Test
public void secondLevelCache() {
SqlSession sqlSession1 = sqlSessionFactory.openSession();
SqlSession sqlSession2 = sqlSessionFactory.openSession();
SqlSession sqlSession3 = sqlSessionFactory.openSession();
IUserMapper mapper1 = sqlSession1.getMapper(IUserMapper.class);
IUserMapper mapper2 = sqlSession2.getMapper(IUserMapper.class);
IUserMapper mapper3 = sqlSession3.getMapper(IUserMapper.class);
User user1 = mapper1.findUserById(1);
sqlSession1.close();
User user = new User();
user.setId(0);
user.setUsername("zhangsan");
mapper3.updateUser(user);
sqlSession3.commit();
User user2 = mapper2.findUserById(1);
System.out.println(user1 == user2);
}
可以发现在执行修改操作之后,mybatis会清空二级缓存,因此会执行两次查询数据库的操作
useCache和flushCache
useCache:单个标签使用,表示可以单独开关二级缓存
flushCache: 表示刷新缓存,默认为true,在执行增删改操作后清空二级缓存,false,可能导致脏读