缓存
缓存主要目的是为了提高查询效率.缓存其实就是一个内存空间,存储在程序的某个地方,存储数据.
mybatis支持缓存的,且有两级缓存
- 一级缓存
- 二级缓存
- 1.1一级缓存
MyBatis的一级缓存是默认的.无需配置,自动实现.
默认的
一级缓存是SqlSession级别
,是指同一个SqlSession发起的多次查询同一条数据,会使用缓存.
1.1.1命中缓存
条件:同一个sqlsession,同一条件(即查询同一条数据)
@Test
public void testOneLevelCache() {
UserMapper mapper1 = sqlSession.getMapper(UserMapper.class);
User user1 = mapper1.findUserById(1);
System.out.println("user1 = " + user1);
System.out.println("-----------------------");
// 命中缓存的前提:1) 同一SqlSession,2) 同一条件
UserMapper mapper2 = sqlSession.getMapper(UserMapper.class);
User user2 = mapper2.findUserById(1);
System.out.println("user2 = " + user2);
}
1.1.2不使用缓存的情况
条件:1.条件不一致 2.sqlsession不一样
@Test
public void testOneLevelCache2() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 获得会话1
SqlSession sqlSession1 = sqlSessionFactory.openSession();
UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);
User user1 = mapper1.findUserById(1);
System.out.println("user1 = " + user1);
System.out.println("---------------------------------" );
// 获得一个会话2
SqlSession sqlSession2 = sqlSessionFactory.openSession();
UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
User user2 = mapper2.findUserById(1);
System.out.println("user2 = " + user2);
}
虽然是同一条数据,但是还是没有使用缓存!为什么?
一级缓存是SqlSession级别,即缓存数据存储在SqlSession中,这次都不是同一个SqlSession,那就无法使用缓存
1.1.3清空缓存
在更新(更新,删除,插入)数据后,要清空缓存,下次重新查最新的数据.避免脏读
1.2二级缓存
二级缓存是Mapper级别
,比SqlSession级别范围更大.
使用时需要手动设置
- 1)需要在全局配置文件中开启缓存()
<settings>
<!-- 开启缓存(默认就是true) -->
<setting name="cacheEnabled" value="true"/>
</settings>
2)需要在mapper中设置caceh即可
<cache/>
映射语句文件中的所有 select 语句的结果将会被缓存。
映射语句文件中的所有 insert、update 和 delete 语句会刷新缓存。
1.2.1使用二级缓存
1.需要在全局配置文件中开启缓存
2.需要在mapper中设置caceh即可
3.每个会话执行完,要关闭流close,才会将查询数据放入缓存
4.实体类需要实例化,实现Serializable接口
1.2.2清空缓存
二级缓存
演示增删改会清空缓存
@Test
public void testTwoLevelCache2() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 获得会话1
SqlSession sqlSession1 = sqlSessionFactory.openSession();
UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);
User user1 = mapper1.findUserById(1);
System.out.println("user1 = " + user1);
// 关闭会话,才会将这次查询的结果放入缓存!!!
sqlSession1.close();
System.out.println("---------------------------------" );
// 获得一个会话2
SqlSession sqlSession2 = sqlSessionFactory.openSession();
UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
User user2 = mapper2.findUserById(1);
System.out.println("user2 = " + user2);
System.out.println("---------------------------------" );
// 只要有增删改都会清空缓存
UserMapper mapper = sqlSession2.getMapper(UserMapper.class);
User user = new User( );
user.setId(2);
user.setUsername("QF");
user.setPassword("qf888");
int i = mapper.updateUser(user);
System.out.println(i > 0?"OK":"ERR" );
// 增删改要提交
sqlSession2.commit();
sqlSession2.close();
System.out.println("---------------------------------" );
// 获得一个会话3
SqlSession sqlSession3 = sqlSessionFactory.openSession();
UserMapper mapper3 = sqlSession3.getMapper(UserMapper.class);
User user3 = mapper3.findUserById(1);
System.out.println("user3 = " + user3);
sqlSession3.close();
}