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. mysql查询最近2天数据

    SELECT * FROM jk_dzbl_zybrbljlb where jlrq >= now()-interval 2 day

  2. UVM——callback机制应用示例

    对应代码: 1.在UVM组件中主操作函数或者任务之前或者之后内嵌callback函数或任务 1 class driver extends uvm_driver #(transaction); 2 `u ...

  3. ESModule导入

    //导入某方法 import pick from "lodash/pick"; //默认导入方式 import { pick } from "lodash"; ...

  4. CodeGym自学笔记03——变量、数据类型

    变量 变量是用来存储数据的特殊实体. 1.在 Java 语言中,所有数据都存储在变量中. 2.最接近的比喻就好比是一个盒子. 3.在 Java 语言中,每个变量都有三个重要的属性:类型.名称和值. - ...

  5. 7.Object

    Object类 超类.基类,所以类的直接或间接父类,位于继承树的最顶层 任何类,如没有书写extends显示继承某个类,都默认直接继承Object类,否则为间接继承 Object类中所定义的方法,是所 ...

  6. 关闭Mac的Microsoft AutoUpdate弹框提示

    macOS安装Microsoft Office for Mac之后,有时候会弹出Microsoft Auto Update微软应用自动更新工具.就像下面这样:(我不知道您会不会烦,我是烦了)如果您也和 ...

  7. Leaflet加载GeoServer发布的WMTS地图服务

    leaflet本身并不支持WMTS服务,需要借助leaflet-tilelayer-wmts插件实现,但是插件是为通用WMTS服务实现的.在使用的过程中出现了无法调用的问题,这里进行了稍微修改. 加载 ...

  8. django操作WEB涉及的几个命令

    1)创建项目bysms django-admin startproject bysms 2)创建应用sales (在bysms目录下执行) python manage.py startapp sale ...

  9. react native 第三方富文本编辑器 wxik/react-native-rich-editor(在移动端使用)

    //更新2021年8月23日 (1)wxik/react-native-rich-editor  个人认为功能比较全,推荐使用 关于使用的案例,官网上有,我直接粘贴我遇到的几个问题 1. 软键盘弹出时 ...

  10. docker学习(dockerfile打jar包为镜像)

    docker打包jar为docker镜像 1.使用Dockerfile打镜像 将spring boot应用打包成jar包放置在/app/applcation路径中 编写dockerfile文件,内容参 ...