MyBatis

月伴飞鱼 2024-09-19 18:09:26
框架相关
支付宝打赏 微信打赏

如果文章对你有帮助,欢迎点击上方按钮打赏作者!

缓存机制

基本概念

SqlSession

  • 代表和数据库的一次会话,向用户提供了操作数据库的方法。

MappedStatement

  • 代表要发往数据库执行的指令,可以理解为是 SQL 的抽象表示。

Executor

  • 代表用来和数据库交互的执行器,接受 MappedStatment 作为参数。

NameSpace

  • 每个 Mapper 文件只能配置一个 NameSpace,用来做 Mapper 文件级别的缓存共享。

一级缓存

在一次 SqlSession 中(数据库会话),程序执行多次查询,且查询条件完全相同,多次查询之间程序没有其他增删改操作。

  • 则第二次及后面的查询可以从缓存中获取数据,避免走数据库。

每个SqlSession中持有了Executor,每个Executor中有一个LocalCache

当用户发起查询时,MyBatis根据当前执行的语句生成MappedStatement

Local Cache进行查询,如果缓存命中的话,直接返回结果给用户。

  • 如果缓存没有命中的话,查询数据库,结果写入Local Cache,最后返回结果给用户。

一级缓存配置:

mybatis-config.xml 文件配置,name=localCacheScope

value有两种值:SESSIONSTATEMENT

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

SESSION:开启一级缓存功能

STATEMENT

  • 缓存只对当前执行的这一个 SQL 语句有效,也就是没有用到一级缓存功能。

一级缓存失效的场景:

不同的SqlSession对应不同的一级缓存

同一个SqlSession但是查询条件不同

同一个SqlSession两次查询期间执行了任何一次增删改操作

同一个SqlSession两次查询期间手动清空了缓存

二级缓存

相对于一级缓存来说,实现了SqlSession之间缓存数据的共享,同时粒度更加的细,能够到NameSpace级别。

通过Cache接口实现类不同的组合,对Cache的可控性也更强。

一级缓存最大的共享范围就是一个 SqlSession 内部,如果多个 SqlSession 之间需要共享缓存,则需要使用到二级缓存。

开启二级缓存后,会使用 CachingExecutor 装饰 Executor,进入一级缓存的查询流程前。

  • 先在CachingExecutor 进行二级缓存的查询。

同一个 NameSpace下的所有操作语句,都影响着同一个Cache

每个 Mapper 文件只能配置一个 NameSpace,用来做 Mapper 文件级别的缓存共享。

<mapper namespace="mapper.StudentMapper"></mapper>

二级缓存被同一个 NameSpace 下的多个 SqlSession 共享,是一个全局的变量。

MyBatis 的二级缓存不适应用于映射文件中存在多表查询的情况。

由于MyBatis的二级缓存是基于NameSpace的。

  • 多表查询语句所在的NameSpace无法感应到其他NameSpace中的语句对多表查询中涉及的表进行的修改,引发脏数据问题。

开启二级缓存需要在 mybatis-config.xml 中配置:

<settingname="cacheEnabled"value="true"/>

缓存查询的顺序

先查询二级缓存,因为二级缓存中可能会有其他程序已经查出来的数据,可以拿来直接使用

  • 如果二级缓存没有命中,再查询一级缓存

  • 如果一级缓存也没有命中,则查询数据库

SqlSession关闭之后,一级缓存中的数据会写入二级缓存

支付宝打赏 微信打赏

如果文章对你有帮助,欢迎点击上方按钮打赏作者!