1.1 基本介绍
什么是缓存 [ Cache ]
- 存在内存中的临时数据。
- 将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题。
为什么使用缓存
减少和数据库的交互次数,减少系统开销,提高系统效率。
什么样的数据能使用缓存
经常查询并且不经常改变的数据。
1.2 Mybatis缓存
- MyBatis包含一个非常强大的查询缓存特性,它可以非常方便地定制和配置缓存。缓存可以极大的提升查询效率。
- MyBatis系统中默认定义了两级缓存:一级缓存和二级缓存。
- 默认情况下,只有一级缓存开启。(SqlSession级别的缓存,也称为本地缓存)
- 二级缓存需要手动开启和配置,他是基于namespace级别的缓存。
- 为了提高扩展性,MyBatis定义了缓存接口Cache。我们可以通过实现Cache接口来自定义二级缓存
1.3 一级缓存
基本介绍
一级缓存是SqlSession级别的缓存,是默认开启的。所以在参数和SQL完全一样的情况下,使用同一个SqlSession对象调用一个Mapper方法,往往
只执行一次SQL,因为使用SelSession第一次查询后,MyBatis会将其放在缓存中,以后再查询的时候,如果没有声明需要刷新,并且缓存没有超时的情况下,SqlSession都会取出当前缓存的数据,而不再次发送SQL到数据库。
一级缓存的范围: 在同一个会话中使用
一级缓存图
1.3.1 代码示例
// 1.验证Mybatis一级缓存
@Test
public void testOneCache(){
// 1.通过工具类得到会话对象
SqlSession sqlSession = MybatisUtils.getSession();
// 2.会话对象的得到mapper接口代理对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
// 根据id查询用户信息,第一次查询,查的是数据库
User user1 = mapper.findById(1);
System.out.println(user1);
// 第二次查询,查询的是一级缓存
User user2 = mapper.findById(1);
System.out.println(user2);
// 关闭会话对象
sqlSession.close();
}
执行结果
上面的代码中我们查询了两次,但最后只执行了一次数据库操作,这就是Mybatis提供给我们的一级缓存在起作用了。因为一级缓存的存在,导致第二次查询id为1的记录时,并没有发出sql语句从数据库中查询数据,而是从一级缓存中查询。
分析结果
一级缓存是SqlSession范围的缓存,执行SqlSession的C(增加)U(更新)D(删除)操作,或者调用clearCache()、commit()、close()方法,都会清空缓存。
1. 第一次发起查询用户id为1的用户信息,先去找缓存中是否有id为1的用户信息,如果没有,从数据库查询用户信息。
2. 得到用户信息,将用户信息存储到一级缓存中。
3. 如果sqlSession去执行commit操作(执行插入、更新、删除),清空SqlSession中的一级缓存,这样做的目的为了让缓存中存储的是最新的信息,避免脏读。
4. 第二次发起查询用户id为1的用户信息,先去找缓存中是否有id为1的用户信息,缓存中有,直接从缓存中获取用户信息。
清除缓存
清空的方式:sqlSession 执行添加、修改、删除、提交、关闭等操作,清空 sqlSession 中的一级缓存数据。
清空的目的:为了让缓存中存放最新数据,避免脏读。
// 1.验证Mybatis一级缓存
@Test
public void testOneCache(){
// 1.通过工具类得到会话对象
SqlSession sqlSession = MybatisUt