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 //这里是二级缓存

参考文章

最新文章

  1. python遍历一个网段的ip地址
  2. js中join函数的使用方法(js输出html标签)
  3. 20145212 实验三《敏捷开发与XP实践》
  4. canvas应用-思维导图
  5. lvs nginx HAProxy优缺点
  6. QT5-控件-QScrollArea-可以用于把一个窗口分割为多个-比如根据图片大小显示滚动条
  7. Servlet转发和重定向的区别
  8. ECMA Script 6_RegExp 正则表达式
  9. Unity Ragdoll 实现死亡效果 心得+坑点总结
  10. mysql入门学习笔记
  11. UVA1623-Enter The Dragon(并查集)
  12. 最小生成树 prime+heap
  13. jQuery-3.事件篇---表单事件
  14. linux计划任务防暴力破解脚本+免密操作
  15. HDU1874畅通project续 dijkstra&&floyd
  16. kernel printk信息显示级别
  17. 完全用nosql轻松打造千万级数据量的微博系统(转)
  18. @SuppressWarnings 参数列表信息
  19. Anaconda常用命令
  20. Redis几个认识误区(转)

热门文章

  1. Android 删除已知路径的文件或文件夹
  2. 通过Sql Server 作业实现定时任务
  3. Word16 供应链的管理论文office真题
  4. Java 8 在使用内存爆了以后会发生什么?hs_err_pid 日志如何看?
  5. MySQL安装最后一步无响应解决方法
  6. pycharm过期解决方案
  7. Nacos安装与启动
  8. macOS 系统安装提示应用程序副本已损坏的解决方法
  9. 网络图片转base64
  10. JVM(二) --- JVM的内存结构