十三、缓存机制
13.1、缓存的简介
??缓存简而来说就是指存在内存中的临时数据,并将用户经常查询的数据放在缓存(内存)中,用户在查询数据就不用从磁盘上(关系型数据库数据文件)查询,从而提高效率。使用缓存可以减少和数据库的交互次数,减少系统开销,从而提高系统效率。如果是经常查询并且不经常改变的数据就可以使用缓存。
13.2、MyBatis缓存
13.2.1、两种MyBatis缓存
-
一级缓存(sqlSession 级缓存):在同一个 sqlSession 中起作用,sqlSession 一旦关闭,一级缓存消失; -
二级缓存(mapper 级缓存):在同一个 mapper 中多个 sqlSession 可以共享的缓存。
13.2.2、补充
- 默认情况下,只有一级缓存开启;
- 二级缓存需要手动开启和配置,它是基于namespace(mapper)级别的缓存;
- 为了提高拓展性,MyBatis定义了缓存接口cache,我们可以通过实现cache接口来自定义二级缓存。
13.3、一级缓存
-
一级缓存属于 mybatis 的默认缓存,默认开启,直接使用; -
当我们执行查询语句时,mybatis 都会将查询的数据存在一级缓存中,直到session 关闭或事务提交或手动清空缓存。
测试在一个Session中查询两次相同记录
Mapper.xml
<select id="queryUserById" resultType="user">
select * from user where user_id = #{user_id}
</select>
Test测试
@Test
public void test1(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.queryUserById(1);
System.out.println(user);
System.out.println("===========================");
User user1 = userMapper.queryUserById(1);
System.out.println(user1);
sqlSession.close();
}
查看日志输出
缓存失效的情况:
- 查询不同的数据;
- 增删改操作,可能会改变原有的数据,因此会刷新缓存;
- 查询不同的Mapper.xml;
- 手动清理缓存。
sqlSession.clearCache();
13.4、二级缓存
??二级缓存是脱离 sqlSession 存在的,而且是同一个 mapper 共享的,所以默认情况对象并不进入二级缓存,需要手动设置要向二级缓存中存放的对象(一般情况下使用比较频繁的对象放入二级缓存)。
- 开启全局缓存
<setting name="cacheEnabled" value="true"/>
- 在需要的mapper中开启二级缓存
<cache/>
??也可以自定义参数
<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>
- 测试
@Test
public void test1(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
SqlSession sqlSession1 = MybatisUtils.getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.queryUserById(1);
System.out.println(user);
sqlSession.close();
UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);
User user1 = userMapper1.queryUserById(1);
System.out.println(user1);
System.out.println(user==user1);
sqlSession1.close();
}
日志输出
问题:需要将实体类序列化,否则就会报错!
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
private Integer user_id;
private String user_name;
private String password;
}
总结:
- 二级缓存必须在同一个Mapper下才有效;
- 所有的数据都会先放在一级缓存中;
- 只有当会话提交,或者关闭的时候,才会提交到二级缓存中。
??当查询一个对象时,会先在二级缓存中查找(该对象允许存入到二级缓存中),如果找到则直接返回,如果找不到则在到一级缓存中查找,如果找到则返回,如果找不到会向数据库发送查询请求,并查询相应的数据,将该数据存入到一级缓存和二级缓存(该对象允许存入到二级缓存中),以备后期使用。
|