MyBatis 缓存

29 阅读3分钟

MyBatis 缓存概述

缓存的概念和作用

  • 缓存是数据交换的缓冲区(称作Cache),是临时存贮数据(一般是使用频繁的数据)的地方。当用户查询数据,首先在缓存中寻找,如果找到了则直接返回。如果找不到,则去数据的来源查找 。
  • 缓存的本质就是用空间换时间,牺牲数据的实时性,以内存中的数据暂时替代从外部读取数据,达到减轻服务端压力,减少网络延迟的效果。

MyBatis 缓存

  • MyBatis 提供的缓存,缓存的是数据库查询的结果。

image.png

MyBatis 日志配置

  • 通过日志查看 MyBatis 的执行过程,执行过程反映了 MyBatis 是否使用了缓存。
  • 参考官网:mybatis.org/mybatis-3/z…
  • 第一步:引入 Log4j 依赖

image.png

  • 第二步:配置 log4j.properties 文件

image.png

MyBatis 一级缓存

  • MyBatis 一级缓存是 SqlSession 级别的,通过同一个 SqlSession 查询的结果会被缓存。下次查询相同的数据时,就会从缓存中直接获取,不会查询数据库。
  • MyBatis 一级缓存是默认开启的。

CASE 1:同一个 SqlSession,相同的查询条件

image.png

image.png

只执行了一次数据库查询,第二次查询使用缓存中的数据。

CASE 2:同一个 SqlSession,不相同的查询条件

image.png

image.png

  • 两次查询的条件不同,第二次查询未命中缓存,执行了两次数据库查询。

CASE 3:不同 SqlSession,相同的查询条件

image.png

image.png

一级缓存是 SqlSession 级别的,SqlSession 之间不能共用一级缓存。

CASE 4:同一个 SqlSession,不同的 mapper 对象

image.png

image.png

CASE 5:同一个 SqlSession,同一个 mapper,不同的方法,执行 SQL 相同

image.png

image.png

命中一级缓存要求以下相同:SqlSession,namespace,执行方法,SQL,参数。

CASE 6:第一次查询没有查到数据,第二次使用相同参数查询

image.png

image.png

“未查询到数据”也是查询结果,也会被缓存下来。

一级缓存失效的情况

  • 不同的 SqlSession
  • 同一个 SqlSession,不同的查询条件
  • 缓存被清空
    • SqlSession 内执行了增、删、改会清空一级缓存
    • 执行 SqlSession 的 clearCache 方法会清空一级缓存

缓存被清空: SqlSession 内执行了增、删、改会清空一级缓存

image.png

image.png

为什么执行了增、删、改 MyBatis 就要清空一级缓存?

  • 因为执行了 DML,数据库中的数据可能发生了变化,缓存中的数据可能过时了,要从数据库中获取最新数据

缓存被清空:执行 SqlSession 的 clearCache 方法会清空一级缓存

image.png

image.png

如何强制不使用一级缓存?

  • 一级缓存的问题:数据实时性得不到保障。如果其他 SqlSession 变更了数据,当前 SqlSession 查到的可能就不是最新数据。
  • 强制不使用一级缓存 在 mybatis-config.xml 核心配置文件中增加配置

image.png

image.png

MyBatis 二级缓存

  • MyBatis 二级缓存是 SqlSessionFactory 级别的,通过同一个 SqlSessionFactory 创建的 SqlSession查询的结果会被缓存。下次查询相同的数据时,就会从缓存中直接获取,不会查询数据库。
  • MyBatis 二级缓存是默认关闭的。

使用二级缓存的步骤

  • mapper.xml 文件中添加标签
  • POJO 类实现 Serializable 接口
  • 关闭 session,一级缓存中的数据才会写入到二级缓存

image.png

image.png

image.png

image.png

  • 执行增、删、改会清空二级缓存

image.png

image.png

MyBatis 缓存查询的顺序

  • 先查询二级缓存,命中二级缓存则直接使用二级缓存中的数据
  • 二级缓存未命中,查询一级缓存,一级缓存命中则直接使用一级缓存中的数据
  • 一级缓存未命中,查询数据库,将查询结果存入一级缓存
  • SqlSession 关闭,将一级缓存中的数据写入二级缓存

image.png

为什么不推荐使用 MyBatis 二级缓存

  • 二级缓存的生命周期比一级缓存长,数据实时性更难以保障。

image.png

也可以通过配置刷新间隔让二级缓存定期失效,但刷新间隔需要配置得合理。