MyBatis 提供了对缓存的支持,分为一级缓存和二级缓存

一级缓存是 SqlSession 级别的缓存。在操作数据库时需要构造 SqlSession 对象,在对象中有一个数据结构(HashMap)用于存储缓存数据。不同的是 SqlSession 之间的缓存数据区(HashMap)是互相不影响。

二级缓存是 Mapper 级别的缓存,多个 SqlSession 去操作同一个 Mapper 的 sql 语句,多个 SqlSession 可以共用二级缓存,二级缓存是跨 SqlSession 的。

一级缓存

具体执行过程如下图所示:

SqlSession 是一个接口,提供了一些 CRUD 的方法,而 SqlSession 的默认实现类是 DefaultSqlSession,DefaultSqlSession 类持有 Executor 接口对象,而 Executor 的默认实现是 BaseExecutor 对象,每个 BaseExecutor 对象都有一个 PerpetualCache 缓存,也就是上图的  Local Cache。

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

  • MyBatis 一级缓存的生命周期和 SqlSession 一致。

  • MyBatis 一级缓存内部设计简单,只是一个没有容量限定的 HashMap,在缓存的功能性上有所欠缺。

  • MyBatis 的一级缓存最大范围是 SqlSession 内部,有多个 SqlSession 或者分布式的环境下,数据库写操作会引起脏数据,建议设定缓存级别为 Statement。

  • 只有在开启了数据库事物【@EnableTransactionManagement】并且处于一个被事物标注的方法下【直接或间接】才会生效。

二级缓存

二级缓存开启后,同一个 namespace 下的所有操作语句,都影响着同一个 Cache,即二级缓存被多个 SqlSession 共享,是一个全局的变量。

当开启缓存后,数据的查询执行的流程就是 二级缓存 -> 一级缓存 -> 数据库。

MyBatis 是默认关闭二级缓存的,因为对于增删改操作频繁的话,那么二级缓存形同虚设,每次都会被清空缓存。

  • MyBatis 的二级缓存相对于一级缓存来说,实现了 SqlSession 之间缓存数据的共享,同时粒度更加的细,能够到 namespace 级别,通过 Cache 接口实现类不同的组合,对 Cache 的可控性也更强。

  • MyBatis 在多表查询时,极大可能会出现脏数据(多表查询语句所在的 namspace 无法感应到其他 namespace 中的语句对多表查询中涉及的表进行的修改),有设计上的缺陷,安全使用二级缓存的条件比较苛刻。

  • 在分布式环境下,由于默认的 MyBatis Cache 实现都是基于本地的,分布式环境下必然会出现读取到脏数据,需要使用集中式缓存将 MyBatis 的 Cache 接口实现,有一定的开发成本,直接使用 Redis、Memcached 等分布式缓存可能成本更低,安全性也更高。

关闭一二级缓存

建议禁用一级与二级缓存,分布式应用程序应该是必须要禁用的,单体应用如果没有禁用一级缓存,则要建议多线程共享同一个SqlSession。

方法一:禁用一级缓存:mybatis没有提供一级缓存的启用、禁用开关,但在Mapper文件对应的语句中增加flushCache="true"可以达到实际禁用一级缓存的效果,一般同时还会加上useCache="false",以便关闭二级缓存;

方法二:将mybatis一级缓存级别设置为statement可以事实上达到禁用一级缓存的效果;

mybatis:
configuration:
local-cache-scope: session //statement 一级缓存
cache-enabled: false //这里是二级缓存

参考文章

mybatis 一级、二级缓存机制的更多相关文章

  1. 延迟加载以及mybatis一级二级缓存

    延迟加载 延迟加载:在真正使用数据时才发起查询,不用的时候不查询,又叫按需查询(懒加载) 立即加载:不管用不用,只要调用方法,直接发起查询 表关系:一对多     多对一     一对一        ...

  2. Hibernate的一级二级缓存机制配置与测试

    特别感谢http://www.cnblogs.com/xiaoluo501395377/p/3377604.html 在本篇随笔里将会分析一下hibernate的缓存机制,包括一级缓存(session ...

  3. mybatis一级二级缓存

    一级缓存分析 不需要任何配置 ,mybatis本身带有 一级缓存是SqlSession范围的缓存,当调用SqlSession的修改,添加,删除,commit(),close()等方法时,就会清空一级缓 ...

  4. 《深入理解mybatis原理7》 MyBatis的二级缓存的设计原理

    <深入理解mybatis原理> MyBatis的二级缓存的设计原理 MyBatis的二级缓存是Application级别的缓存,它可以提高对数据库查询的效率,以提高应用的性能.本文将全面分 ...

  5. 《深入理解mybatis原理》 MyBatis的二级缓存的设计原理

    MyBatis的二级缓存是Application级别的缓存,它可以提高对数据库查询的效率,以提高应用的性能.本文将全面分析MyBatis的二级缓存的设计原理. 如上图所示,当开一个会话时,一个SqlS ...

  6. mybatis深入理解(六)-----MyBatis的二级缓存的设计原理

    MyBatis的二级缓存是Application级别的缓存,它可以提高对数据库查询的效率,以提高应用的性能.本文将全面分析MyBatis的二级缓存的设计原理. 1.MyBatis的缓存机制整体设计以及 ...

  7. Mybatis五(一级二级缓存、第三方缓存)

    一级缓存 Mybatis对缓存提供支持,但是在没有配置的默认情况下,它只开启一级缓存,一级缓存只是相对于同一个SqlSession而言.所以在参数和SQL完全一样的情况下,我们使用同一个SqlSess ...

  8. Mybatis的一级二级缓存

    Mybatis提供了缓存机制,可以减轻数据库的压力,提高性能 Mybatis的缓存分为两级:一个是一级缓存,一个二级缓存 一级缓存:即默认使用的缓存SqlSession级别的缓存,只在sqlsessi ...

  9. 使用Redis做MyBatis的二级缓存

    使用Redis做MyBatis的二级缓存 通常为了减轻数据库的压力,我们会引入缓存.在Dao查询数据库之前,先去缓存中找是否有要找的数据,如果有则用缓存中的数据即可,就不用查询数据库了. 如果没有才去 ...

  10. 【面试普通人VS高手系列】说一说Mybatis里面的缓存机制

    一个工作了 5年的程序员,在私信里面不断向我诉苦. 他说,他用了Mybatis这么久,怎么滴也算是精通Mybatis了吧. 结果竟然在Mybatis这个面试题上翻车了! 真的好烦! 好吧,我们今天来看 ...

随机推荐

  1. 【转载】Python(cx_oracle)的DPI-1047错误

    转自:https://blog.csdn.net/weixin_45158749/article/details/124800132 Python(cx_oracle)的DPI-1047错误 步步 F ...

  2. 同一ip地址不同的主机冲突解决

    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: REMOTE HOST IDENTIFICATION HA ...

  3. .net core 3.1 上传大文件报错413 Payload Too Large

    IIS配置如下 https://www.cnblogs.com/hallejuayahaha/p/12884347.html 代码里面新增 services.Configure<FormOpti ...

  4. [UnityShader]unity中2D Sprite显示阴影和接受阴影

    首先是效果 要让2D显示阴影,首先假设知道Unity阴影来源(shader中的ShadowCaster) 最简单的方法是,首先从官网下载Sprite-Default.Shader,查看源码 然后复制粘 ...

  5. shell实现接口初次失败告警,恢复也发送一次通知

    1.该shell判断 第一次失败告警,接口恢复发送一次通知 参数:一个参数接口返回结果0 表示成功 1表示失败 脚本详情 [root@localhost bd]# more bd-new.sh #!/ ...

  6. k8s安装gitlab-ce

    docker镜像打包 根据官方说明:gitlaby docker镜像中已经不包含邮件代理传输,需要重新打包镜像 FROM gitlab/gitlab-ce RUN apt-get update &am ...

  7. React子组件继承父组件的props

    https://zh-hans.reactjs.org/warnings/unknown-prop.html

  8. speedtest测速

    wget https://raw.github.com/sivel/speedtest-cli/master/speedtest.py chmod a+rx speedtest.py mv speed ...

  9. [记] OpenCV4 源码编译安装 | 记录

    OpenCV4 源码编译安装 | 记录 参考资料 官方文档:https://docs.opencv.org/4.x/d7/d9f/tutorial_linux_install.html 环境 wsl2 ...

  10. SpringBoot-集成PageHelper及使用

    1.添加依赖 1 <dependency> 2 <groupId>com.github.pagehelper</groupId> 3 <artifactId& ...