MyBatis专栏3 - 一级缓存

知识点-一级缓存

1.目标

  • 掌握MyBatis一级缓存

2.路径

  1. 证明一级缓存的存在
  2. 一级缓存分析
  3. 测试一级缓存清空

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.小结

  1. 一级缓存: 依赖sqlSession对象的, 自带的不可卸载的. 一级缓存的生命周期和sqlSession一致
  2. 一级缓存清空
    • sqlSession销毁
    • 增删改 提交之后

猜你喜欢

转载自blog.csdn.net/malipku/article/details/113732508