【Mybatis】浅谈Mybatis的缓存机制,一级缓存和二级缓存

目录

1. 缓存机制介绍

2. 一级缓存

3. 二级缓存

4. mybatis缓存执行流程


1. 缓存机制介绍

MyBatis 的缓存机制是为了提高应用程序的性能而设计的,通过缓存策略来减少数据库的查询次数。MyBatis 提供了两种类型的缓存:一级缓存和二级缓存。

  • 默认情况下,只有一级缓存(session级别的缓存,也称为本地缓存)开启。
  • 默认情况下,二级缓存是关闭的,需要显式启用。
  • 为了提高扩展性。MyBatis定义了缓存接口Cache。我们可以通过实现Cache接口来自定义二级缓存

一级缓存和二级缓存图示

2. 一级缓存

一级缓存是默认启用的,它是基于 SqlSession 的缓存。这意味着在同一个 SqlSession 的生命周期内,对于相同的 SQL 查询,MyBatis 会先检查缓存中是否有之前执行该查询的结果,如果有,则直接从缓存中获取,而不是再次执行 SQL 查询。

  • 作用范围:一级缓存的作用范围仅限于同一个 SqlSession。
  • 自动管理:一级缓存由 MyBatis 自动管理,无需任何配置。
  • 失效条件
    • 当执行更新操作(包括 insert、update 或 delete)时,一级缓存会被清空。
    • 当 SqlSession 关闭或执行了 clearCache() 方法时,一级缓存也会被清空。
    • 如果 SqlSession 设置了 autoCommit 为 true 并且执行了 commit,那么缓存也会被清空。
    • 将一级缓存的作用域设置为语句级别(localCacheScope设置为STATEMENT

一级缓存启用测试

【说明】上面代码表明,测试方法中调用了两次查询方法,但是sql语句就执行了一次就得到了结果,这说明第一次查询后会记录在一级缓存中,如果再次执行sql语句时就会向一级缓存中查看是否此次qlSession会话中是否已经执行过该sql,执行过,就直接到缓存中拿结果,未执行,就向数据库中查询。

一句换:相同的sql语句,没必要执行,到一级缓存中直接拿)

一级缓存失效测试(以执行了 clearCache() 方法时为例

【说明】因为清空了一级缓存,则第二次同样的查询语句在一级缓存中没有找到,就只能向数据找了,所以就执行了两次sql语句。但是为啥查询的对象的属性值相同,确输出 false (地址值不同)?

        这是因为第一次查询的结果 user1 和第二次查询的结果 user2 尽管具有相同的属性值,但由于它们是由两次不同的数据库查询创建的,因此它们是两个不同的对象实例。因此,user1 == user2 返回 false,表示这两个对象的内存地址不同。

3. 二级缓存

二级缓存是一种可选的缓存机制,它在同一个命名空间(namespace)下的多个 SqlSession 之间共享数据。这意味着如果多个 SqlSession 执行相同的查询语句并且这些 SqlSession 都属于同一个命名空间,那么它们就可以共享缓存中的数据。

  • 作用范围:二级缓存的作用范围是全局的,可以在不同的 SqlSession 实例间共享数据。
  • 启用方式
    • 为了启用二级缓存,需要在 配置文件<mapper> 标签中加入 <cache/> 元素。
    • 默认情况下,二级缓存是关闭的,需要显式启用。
    • 你可以为每个 <mapper> 定制缓存策略,例如设置缓存过期时间、缓存存储机制等。
  • 失效条件
    • 默认情况下,当执行了更新操作后,二级缓存不会被清空,除非显式配置。
    • 二级缓存可以通过调用 clear() 方法来手动清空。
    • 二级缓存的数据一致性问题需要特别注意,因为它可能在多个线程或多个事务之间共享。

配置二级缓存代码

<mapper namespace="com.example.mapper.UserMapper">
    <cache type="PERPETUAL" eviction="LRU" flushInterval="60000" size="512" readOnly="true"/>
    
    <!-- SQL 映射 -->
</mapper>

各个参数说明

  • type: 缓存实现类型,默认为 PERPETUAL(永不过期),可以改为其他实现,如 EHCache。
  • eviction: 指定缓存淘汰策略,默认为 LRU(最近最少使用)。
  • flushInterval: 指定缓存刷新间隔时间(毫秒),默认不自动刷新。
  • size: 缓存的最大容量。
  • readOnly: 如果设置为 true,则缓存中的数据被认为是只读的,这样在执行更新操作时就不会刷新缓存。

【注意】

        1. 二级缓存可能会导致数据一致性问题,因此建议在只读操作或者对数据一致性要求较              低的应用中使用。

        2. 对于需要更新操作的场景,应该谨慎使用二级缓存,以避免潜在的数据不一致问题。

4. mybatis缓存执行流程

总流程

  1. 查询开始

    • 当执行一个 SQL 查询时,MyBatis 会首先检查一级缓存中是否存在相同 SQL 语句的结果。
  2. 一级缓存命中

    • 如果一级缓存中有对应的查询结果,MyBatis 将直接从一级缓存中获取结果,而不执行 SQL 语句。
    • 这个结果将被返回给调用者。
  3. 一级缓存未命中

    • 如果一级缓存中没有找到查询结果,MyBatis 会检查二级缓存(如果启用)。
  4. 二级缓存命中

    • 如果二级缓存中有对应的查询结果,MyBatis 将直接从二级缓存中获取结果,而不执行 SQL 语句。
    • 这个结果将被返回给调用者。
  5. 二级缓存未命中

    • 如果二级缓存中也没有找到查询结果,MyBatis 会执行 SQL 语句,并将结果保存到一级缓存中(默认)和二级缓存中(如果启用)。
    • 这个结果同样会被返回给调用者。
  6. 缓存失效

    • 当执行了更新操作(包括 insert、update 或 delete)时,一级缓存会被清空。
    • 二级缓存默认不会被清空,但可以配置为在执行更新操作后清空。
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值