MyBatis的一级缓存是SqlSession级别的缓存,也就是说,只要SqlSession对象未关闭,那么查询到的结果都会被缓存下来。但是,有些情况下,MyBatis会使一级缓存失效,下面我们来详细介绍这些情况。
SqlSession关闭
当SqlSession关闭时,一级缓存会失效,因为缓存中的数据会被清空。例如:
代码语言:javascript复制SqlSession sqlSession = sqlSessionFactory.openSession();
// 第一次查询,结果会被缓存
User user = sqlSession.selectOne("com.example.UserMapper.selectUserById", 1);
// 关闭SqlSession,缓存会失效
sqlSession.close();
// 第二次查询,会重新查询数据库
SqlSession sqlSession2 = sqlSessionFactory.openSession();
User user2 = sqlSession2.selectOne("com.example.UserMapper.selectUserById", 1);
sqlSession2.close();
在上面的示例中,我们首先获取了一个SqlSession对象,执行了第一次查询,查询到的结果被缓存到该SqlSession对象的缓存中。然后,我们关闭了该SqlSession对象,缓存也随之失效。接着,我们获取了一个新的SqlSession对象,执行了第二次查询,由于缓存已经失效,MyBatis会重新查询数据库获取结果。
手动清空缓存
我们可以通过调用SqlSession的clearCache()方法来手动清空缓存。例如:
代码语言:javascript复制SqlSession sqlSession = sqlSessionFactory.openSession();
// 第一次查询,结果会被缓存
User user = sqlSession.selectOne("com.example.UserMapper.selectUserById", 1);
// 清空缓存
sqlSession.clearCache();
// 第二次查询,会重新查询数据库
User user2 = sqlSession.selectOne("com.example.UserMapper.selectUserById", 1);
sqlSession.close();
在上面的示例中,我们执行了第一次查询,并将查询结果缓存到SqlSession对象的缓存中。接着,我们手动清空了缓存,然后执行了第二次查询,由于缓存已经被清空,MyBatis会重新查询数据库获取结果。
执行了更新操作
当我们执行了增、删、改操作后,一级缓存也会失效,因为更新操作会对数据进行修改,而缓存中的数据可能已经过时了。例如:
代码语言:javascript复制SqlSession sqlSession = sqlSessionFactory.openSession();
// 第一次查询,结果会被缓存
User user = sqlSession.selectOne("com.example.UserMapper.selectUserById", 1);
// 执行更新操作,缓存会失效
User updateUser = new User();
updateUser.setId(1);
updateUser.setName("newName");
sqlSession.update("com.example.UserMapper.updateUserById", updateUser);
// 第二次查询,会重新查询数据库
User user2 = sqlSession.selectOne("com.example.UserMapper.selectUserById", 1);
sqlSession.close();
在上面的示例中,我们首先执行了第一次查询,查询到的结果被缓存到SqlSession对象的缓存