十三、缓存机制

十三、缓存机制

13.1、缓存的简介

  缓存简而来说就是指存在内存中的临时数据,并将用户经常查询的数据放在缓存(内存)中,用户在查询数据就不用从磁盘上(关系型数据库数据文件)查询,从而提高效率。使用缓存可以减少和数据库的交互次数,减少系统开销,从而提高系统效率。如果是经常查询并且不经常改变的数据就可以使用缓存。

13.2、MyBatis缓存

13.2.1、两种MyBatis缓存
  1. 一级缓存(sqlSession 级缓存):在同一个 sqlSession 中起作用,sqlSession 一旦关闭,一级缓存消失;

  2. 二级缓存(mapper 级缓存):在同一个 mapper 中多个 sqlSession 可以共享的缓存。

13.2.2、补充
  1. 默认情况下,只有一级缓存开启;
  2. 二级缓存需要手动开启和配置,它是基于namespace(mapper)级别的缓存;
  3. 为了提高拓展性,MyBatis定义了缓存接口cache,我们可以通过实现cache接口来自定义二级缓存。

13.3、一级缓存

  1. 一级缓存属于 mybatis 的默认缓存,默认开启,直接使用;

  2. 当我们执行查询语句时,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();
}

查看日志输出
请添加图片描述

缓存失效的情况:

  1. 查询不同的数据;
  2. 增删改操作,可能会改变原有的数据,因此会刷新缓存;
  3. 查询不同的Mapper.xml;
  4. 手动清理缓存。
//手动清理缓存
sqlSession.clearCache();

13.4、二级缓存

  二级缓存是脱离 sqlSession 存在的,而且是同一个 mapper 共享的,所以默认情况对象并不进入二级缓存,需要手动设置要向二级缓存中存放的对象(一般情况下使用比较频繁的对象放入二级缓存)。

  1. 开启全局缓存
<!--显示的开启全局缓存-->
<setting name="cacheEnabled" value="true"/>
  1. 在需要的mapper中开启二级缓存
<!--在当前Mapper.xml中开启二级缓存-->
<cache/>

  也可以自定义参数

<!--在当前Mapper.xml中开启二级缓存-->
<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>
  1. 测试
@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;
}

总结:

  1. 二级缓存必须在同一个Mapper下才有效;
  2. 所有的数据都会先放在一级缓存中;
  3. 只有当会话提交,或者关闭的时候,才会提交到二级缓存中。

  当查询一个对象时,会先在二级缓存中查找(该对象允许存入到二级缓存中),如果找到则直接返回,如果找不到则在到一级缓存中查找,如果找到则返回,如果找不到会向数据库发送查询请求,并查询相应的数据,将该数据存入到一级缓存和二级缓存(该对象允许存入到二级缓存中),以备后期使用。

  • 13
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 20
    评论
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

&小小白&

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值