知识点-一级缓存
1.目标
- 掌握MyBatis一级缓存
2.路径
- 证明一级缓存的存在
- 一级缓存分析
- 测试一级缓存清空
3.讲解
3.1证明一级缓存的存在
@Test
public void testFindAll(){
//1. 获取sqlSession对象
SqlSession sqlSession = SqlSessionFactoryUtils.openSession();
//2. 通过sqlSession对象获取UserDao接口的代理对象
UserDao userDao = sqlSession.getMapper(UserDao.class);
//3. 调用UserDao接口的代理对象的findAll方法获取所有联系人的信息
List<User> userList = userDao.findAll();
for (User user : userList) {
System.out.println(user);
}
System.out.println("分割线----------------------------------");
UserDao userDao2 = sqlSession.getMapper(UserDao.class);
List<User> userList2 = userDao2.findAll();
for (User user : userList2) {
System.out.println(user);
}
//4. 提交事务关闭资源
SqlSessionFactoryUtils.commitAndClose(sqlSession);
}
3.2一级缓存分析
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2ufuGX46-1612624604781)(img/tu_2-1572949193589.png)]
第一次发起查询用户 id 为 1 的用户信息,先去找缓存中是否有 id 为 1 的用户信息,如果没有,从数据库查询用户信息。得到用户信息,将用户信息存储到一级缓存中。第二次发起查询用户 id 为 1 的用户信息,先去找缓存中是否有 id 为 1 的用户信息,缓存中有,直接从缓存中获取用户信息。
如果 sqlSession 去执行 commit操作(执行插入、更新、删除),清空 SqlSession 中的一级缓存,这样做的目的为了让缓存中存储的是最新的信息,避免脏读。
3.3测试一级缓存清空
- 调用sqlSession的commit()或者clearCache()或者close()都能清除一级缓存
@Test
public void testFindAll(){
//1. 获取sqlSession对象
SqlSession sqlSession = SqlSessionFactoryUtils.openSession();
//2. 通过sqlSession对象获取UserDao接口的代理对象
UserDao userDao = sqlSession.getMapper(UserDao.class);
//3. 调用UserDao接口的代理对象的findAll方法获取所有联系人的信息
List<User> userList = userDao.findAll();
for (User user : userList) {
System.out.println(user);
}
System.out.println("分割线----------------------------------");
//清除一级缓存: 1. sqlSession.close() 2. sqlSession.commit() 3. sqlSession.clearCache() 4. 数据发生增删改
sqlSession.clearCache()
UserDao userDao2 = sqlSession.getMapper(UserDao.class);
List<User> userList2 = userDao2.findAll();
for (User user : userList2) {
System.out.println(user);
}
//4. 提交事务关闭资源
SqlSessionFactoryUtils.commitAndClose(sqlSession);
}
- 更新数据也会清空一级缓存
@Test
public void testFindAll(){
//1. 获取sqlSession对象
SqlSession sqlSession = SqlSessionFactoryUtils.openSession();
//2. 通过sqlSession对象获取UserDao接口的代理对象
UserDao userDao = sqlSession.getMapper(UserDao.class);
//3. 调用UserDao接口的代理对象的findAll方法获取所有联系人的信息
List<User> userList = userDao.findAll();
for (User user : userList) {
System.out.println(user);
}
System.out.println("分割线----------------------------------");
//清除一级缓存: 1. sqlSession.close() 2. sqlSession.commit() 3. sqlSession.clearCache() 4. 数据发生增删改
userDao.deleteById(9);
UserDao userDao2 = sqlSession.getMapper(UserDao.class);
List<User> userList2 = userDao2.findAll();
for (User user : userList2) {
System.out.println(user);
}
//4. 提交事务关闭资源
SqlSessionFactoryUtils.commitAndClose(sqlSession);
}
4.小结
- 一级缓存: 依赖sqlSession对象的, 自带的不可卸载的. 一级缓存的生命周期和sqlSession一致
- 一级缓存清空
- sqlSession销毁
- 增删改 提交之后