MyBatis缓存机制

本文详细介绍了MyBatis的一级和二级缓存机制。一级缓存默认开启,存在于SqlSession中,不同SqlSession之间无法共享。二级缓存允许跨SqlSession共享数据,需要在全局配置及映射文件中开启,并在数据变更后失效。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

程序与数据库交互的过程也是一个比较耗费性能的的过程,所以一般都会通过缓存来减少与数据库的直接交互,提升程序的运行效率。

一级缓存

MyBatis中默认开启了SqlSession缓存,即同一个SqlSession对象调用同一个<select>时,只有第一次访问数据库,第一次之后把查询结果缓存到SqlSession缓存区(内存)中。

缓存的是statement对象,在mybatis中一个<select>对应一个statement对象,且缓存的有效范围必须是同一个SqlSession对象。

例如,同一个SqlSession执行同一个<select>查询的情况;

在这里插入图片描述

在这里插入图片描述

每个SqlSession中持有了Executor,每个Executor中有一个LocalCache。当用户发起查询时,MyBatis根据当前执行的语句生成MappedStatement,在Local Cache进行查询,如果缓存命中的话,直接返回结果给用户,如果缓存没有命中的话,查询数据库,结果写入Local Cache,最后返回结果给用户。

在这里插入图片描述

如果执行了修改数据的操作(更新、新增、删除),会造成缓存失效,例如在第三次查询之前执行了新增:

在这里插入图片描述

第二次查询依然走的是缓存,执行完新增操作后,第三次查询缓存失效,查询的数据库。

在这里插入图片描述

新开一个SqlSession对象进行数据修改操作:

在这里插入图片描述

由于一级缓存的有效范围是同一个SqlSession,所以另外一个SqlSession执行的修改操作不会使第一个SqlSession的缓存失效,所以第三次查询依然走的是缓存,此时查询到的是“脏数据”。

在这里插入图片描述

一级缓存的执行时序图:

在这里插入图片描述

如果缓存命中,直接从缓存区返回查询结果;如果缓存没有命中,将查询数据库,把数据库查询到的结果缓存到缓存区,并返回查询结果。

二级缓存

一级缓存的有效范围是同一个SqlSession内,如果需要在不同的SqlSession中共享缓存,则需要用到二级缓存。开启了二级缓存后,进入一级缓存之前会先进行二级缓存的查询。

在这里插入图片描述

开启二级缓存需要在mybatis全局配置文件中配置相应的setting标签:

<setting name="cacheEnabled" value="true"/>

同时需要在sql语句映射文件mapper.xml中添加:

<cache readOnly="true"/>

当SqlSession对象commit()时会把SqlSession缓存的数据flush到二级缓存中:

在这里插入图片描述

上述例子中session和session2都是在最后才提交,所以二级缓存不生效:

在这里插入图片描述

稍微修改一下,在执行第一条查询语句的时候,进行session提交:

在这里插入图片描述

由于在执行第一条查询sql的时候就提交了,所以已经将SqlSession缓存flush到了二级缓存,后面的sql语句会命中缓存。

在这里插入图片描述

二级缓存在SqlSession执行了改变数据库的操作(更新、删除、新增)之后会失效,例如:

在这里插入图片描述

在执行第一条sql语句后提交了,所以第二条sql语句会命中缓存,之后session2执行了新增sql,会导致二级缓存失效:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值