【mybatis】Mybatis中的一级、二级缓存

【mybatis】简介

【mybatis】mybatis & mybatis-plus & hibernate的区别

【mybatis】核心成员分析

【mybatis】Mybatis的工作流程

目录

概览

一级缓存

二级缓存 

分析

一级缓存

一级缓存的创建与查询

一级缓存的删除

总结

二级缓存

二级缓存的创建与查询

二级缓存的删除

总结


概览

一级缓存

我们知道Mybatis中有一级和二级缓存,默认一级缓存是打开的且缓存作用域是session,是在与数据库交互之前的openSession,到最后closeSession之间,同一个sqlSession里的所有查询都将会被缓存起来,我们可以在mybatisConfig.xml下的<settings>里可以配置

<settings>
    <setting name="localCacheScope" value="SESSION"/>
</settings>

MyBatis 利用本地缓存机制(Local Cache)防止循环引用(circular references)和加速联复嵌套査询。
默认值为 SESSION,这种情况下会缓存一个会话中执行的所有查询。若设置值为 STATEMENT,本地会话仅用在语句执行上,对相同 SqlScssion 的不同调用将不会共享数据。

我们从下面这张图里也能看到,我在同一个sqlSession里执行了两次查询,只有第一次查询了DB,第二次直接从缓存中拿到的。当执行到update/delete/insert操作,一级缓存是会清除的。

二级缓存 

二级缓存的作用域的Mapper级别的,默认是不开启二级缓存,如果我们开启的话,有以下几个步骤:

  • 在mybatisConfig.xml下的<settings>里可以配置
<settings>
    <setting name="cacheEnabled" value="true"/>
</settings>

  • 在Mapper里配置cache属性 
<cache/>

  • 在映射语句里使用缓存 
useCache="true"

如果开启了二级缓存之后,由于他的作用域是Mapper级别的,所以如果A接口里有查询 selectByPrimaryKey 方法,那么这个结果会被缓存在该Mapper中,如果再来了个B接口也有查询 selectByPrimaryKey 方法,虽然是两级接口不同的sqlSession,但也是会走缓存的。

当执行到update/delete/insert操作,二级缓存是会清除的。

分析

一级缓存

一级缓存的实现比较简单,定义了一个cache接口,实现类 PerpetualCache 里维护了一个 HashMap 来实现一级缓存的 增删查的功能

一级缓存的创建与查询

我们在 BaseExecutor 里看到了有 创建缓存的key的地方 createCacheKey()

具体看看缓存的 key 是由哪些数据组成的

一级缓存的get()和put()方法是在查询的时候用到的,和我们平时一样,查询的时候先查询缓存,缓存中不为空的话,就直接返回了,缓存中为空的话,就继续查询DB,然后把查询结果放进缓存里,很容易理解,下面两张图就是get()和put()。

一级缓存的删除

按照我们正常的思维,缓存应该是在做 update(insert/delete也属于update) 操作的时候会删除掉,我们一起看看源码来证实一下。

总结

一级缓存是作用于session的,同一个sqlSession里的查询操作会被缓存,接下来再来做同样的查询操作就会直接从缓存中获取(statementId:Sql语句的所在位置 包名 + 类名 + SQL名称,sql语句,参数等等都必须要一样才行,因为这些组成了缓存的key),

但是如果同一个sqlSession里的两次查询操作中间有过update操作,则缓存将会被清除掉。

二级缓存

如果开启了二级缓存之后呢,DefaultSqlSession 里的 select 方法将会先走 CachingExecutor 查询缓存,缓存中没有的话再走 BaseExecutor,在 BaseExecutor 中 会先查询一级缓存,一级缓存为空的话再查询DB,所以二级缓存比一级缓存更优先。二级缓存 > 一级缓存 > DB

接下来会去TransactionalCacheManager 里查询二级缓存,这个 TransactionalCacheManager 就是服务二级缓存的

二级缓存使用实现类 TransactionalCache 里维护了一个 HashMap 来实现一级缓存的 增删查的功能

我这边先举个例子说明一下只有当session提交之后才能把数据放进二级缓存中

但是下面这种情况就会走二级缓存(User对象一定要实现Serializable接口)

二级缓存的创建与查询

下面就是cacheKey

二级缓存的删除

也是update/insert/delete操作的时候,如果我们在映射语句配置了 flushCache="true" 属性的话,就会删除缓存

总结

二级缓存默认是不开启的,如果我们想使用的话,需要在三个地方进行配置。

二级缓存如果打开的话,会先查询二级缓存,再查询一级缓存,最后再查询DB。

session必须提交,才能把数据存储到二级缓存里。

二级缓存一般不推荐使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

maple 枫

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

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

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

打赏作者

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

抵扣说明:

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

余额充值