[Mybatis]-[基础支持层]-一级缓存支持

该系列文章针对 Mybatis 3.5.1 版本

Mybatis 中针对缓存的使用,可以分为:一级缓存和二级缓存。

一、一级缓存

一级缓存在 Mybatis 中默认是开启并生效的。

一级缓存存在两种作用范围:

  • SESSION(默认)
    在同一个 SqlSession 中多次执行同一个查询,除第一次走数据库,剩下的都走缓存
  • STATEMENT
    每执行完一个 Mapper 中的语句后都会将一级缓存清除。

在 Mybatis 中,SQL 查询的发起与执行的逻辑处理可以划分为核心处理层,在核心处理层中,所有执行操作的起始都是 Executor 执行器。

执行器实现类图如下

[Mybatis]-[基础支持层]-一级缓存支持

如图,所有 Executor 执行器的实现都继承了抽象父类 BaseExecutor ,
同时 BaseExecutor 是一个模板抽象类,定义了 Executor 的执行结构。

而 一级缓存的相关定义,定义在了 BaseExecutor ,也就是说,所有的 Executor 都支持一级缓存。

1.1、一级缓存在 BaseExecutor 中的定义

关于一级缓存的定义,在 BaseExecutor 构造函数中定义了(意味着,所有实现类,所有的 Executor 在初始化时,即定义了一级缓存),相关代码如下:

[Mybatis]-[基础支持层]-一级缓存支持

如代码所示,一级缓存,就是一个单纯的缓存实现 PerpetualCache,不具备任何功能增强。

1.2、一级缓存在 BaseExecutor 中的使用

Mybatis 对一级缓存使用逻辑如下:

  • 针对查询查询得到缓存,直接从缓存中取结果并返回查询不到缓存,从数据库中查询,然后更新缓存,并返回结果
  • 针对,增删改,涉及到增删改的操作,直接清除缓存

1.3、查询关键代码如下:

  • 命中缓存直接返回逻辑(BaseExecutor#query):
[Mybatis]-[基础支持层]-一级缓存支持
  • 缓存未命中,查询数据库,存缓存并返回(BaseExecutor#query->BaseExecutor#queryFromDatabase
[Mybatis]-[基础支持层]-一级缓存支持
  • 缓存永远无法命中

存在两种情况缓存永远无法命中

第一种:一级缓存存在作用域,如果作用域为 STATEMENT,一级缓存是无效的,因为存了马上被删了。

第二种:Mapper.xml 中 <select> 查询语句配置了 flushCache=true,每次查询前会先清除缓存,缓存永远无法命中

相关代码如下(BaseExecutor#query

[Mybatis]-[基础支持层]-一级缓存支持

1.4、更新关键代码如下

Mybatis 中增删改的操作都是由 Executor#update 来处理,来看其在 BaseExecutor#update 中的代码,如下:

[Mybatis]-[基础支持层]-一级缓存支持

如上述代码,增删改前,直接清除了一级缓存。

二、通过代码测试验证一级缓存存在

以 一级缓存的作用域进行验证,

2.1、STATEMENT

当 一级缓存 的作用域改为 STATEMENT 时,每执行一次 Mapper 中的语句后会将一级缓存清除。此时一级缓存相当于摆设。

step1、设置一级缓存作用范围为 STATEMENT(mybatis-config.xml中)

[Mybatis]-[基础支持层]-一级缓存支持

step2、相关代码

[Mybatis]-[基础支持层]-一级缓存支持

step3、控制台打印信息

[Mybatis]-[基础支持层]-一级缓存支持

从控制台打印的 SQL 能够知道,查询语句执行了两次。

一级缓存作用范围为STATEMENT时,每一次mapper 接口的调用,缓存都会被刷新,相当于缓存没什么卵用

2.2、SESSION

当 一级缓存 的作用范围是 SESSION 时,在同一个 SESSION 中,多次进行同一个查询,只有第一次查询会执行SQL语句,其他相同的SQL查询,走的是一级缓存。

step1、设置一级缓存作用范围为 SESSION (mybatis-config.xml中)

[Mybatis]-[基础支持层]-一级缓存支持

step2、相关代码

[Mybatis]-[基础支持层]-一级缓存支持

step3、控制台打印信息

[Mybatis]-[基础支持层]-一级缓存支持

从控制台打印能够得知:
在 SESSION 范围,同一 SqlSession 执行多次相同sql语句,除第一次外,其余都会直接命中一级缓存。
不同 SqlSession 中执行的相同 sql 不会命中缓存。

来源:花好夜猿,本文观点不代表自营销立场,网址:https://www.zyxiao.com/p/86152

发表评论

登录后才能评论
侵权联系
返回顶部