对于Mybatis缓存分作用域等维度区别一、二级缓存特点如下图:

    

  分析缓存源码首先得找到缓存操作的入口:前面已经分析,sqlsesion.close()仅对一级缓存有影响,而update等对一/二级缓存均有影响。那从session为入口分析一级缓存,从mapper分析二级缓存。

  对于缓存的作用域,之前文章五、MyBatis缓存初体验 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)中已经验证,下面主要从底层数据结构这个维度理解一二级缓存。既然都是基于Perpetualcache的HashMap本地缓存,那么通过调试跟踪到其源码所在位置分析:

    

  PerpetualCache是对JUC中Cache接口的实现,其核心结构为命名为cache的Map<Object, Object>;所以缓存实际就是一个附带id的HashMap。实际上是不是只要实现了JUC中Cache接口均可以作为Mybatis备用缓存???当然可以,可参考MyBatis缓存Cache包 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)

  一级缓存

  跟踪调试仅使用一级缓存的代码,调试信息发现,

     ,

  即可知SimpleExectutor或其上级父类中对一级缓存进行处理,跟踪调试信息,可得如下调用链(查看MyBatis中执行器Executor框架 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)):

  一级缓存功能由BaseExecutor类实现,即意味着每个实际执行器都具有这一级的功能。

  

  那么其具体应用逻辑为何?查看源码如下:

  从源码分析可得:如果设置了每次查询都清缓存,那么每次查询清缓存。同时查询之前判断localCache中是否有当前查询statement.id的相应数据,如果有则直接从一级缓存中获取结果,否则进行查询数据库的操作。

  二级缓存

  二级缓存的作用范围是一个命名空间(即一个映射文件或多个mapper文件同一个命名空间),而且可以实现多个命名空间共享一个缓存。跟踪二级缓存,其建立在mapper配置文件解析过程中即建立,而不是在opensession中。

  二级缓存默认开启,如取消采用如下配置:

  <settings>
   <setting name="cacheEnabled" value="false"/>
  </settings>
  注解方式在mapper接口中使用如下注解,二级缓存生效,否则开启亦不生效。同理在mapper.xml文件中也需配置<cache></cache>表示二级缓存生效

  通过注解开启二级缓存,查看注解源码

   

  可知默认使用PerpetualCache的实现,通过implementation属性,说明二级缓存是可配置的。可以配置用户需要使用的第三方或自定义缓存,比如redis。

  那二级缓存是如何工作的?我们开启二级缓存通过调试查看源码,如下:

  

  可知CachingExecutor中首先查询二级缓存,如果查询结果为空则业务逻辑有simpleExecutor处理即一级缓存的使用逻辑。

  开篇提到,sqlSession.close仅对一级缓存清空二级缓存无影响,以及update等操作对一二级缓存均清空,那么通过close和update源码分别来证实:

  分析CachingExecutor中close的业务逻辑:

  

  首先处理二级缓存rollback或者commit,再处理一级缓存赋值null。所以close操作会清空一级缓存,二级缓存强制回退或者提交数据。

  分析CachingExecutor中update的业务逻辑,显然与close方法不同,如下:

  在上面分析过程中都遇到了CachingExecutor的一个属性,tcm——啥玩意?TransactionalCacheManager

  MyBatis将Cache,TransactionalCache做了映射,而不是和一级缓存保存一致,直接使用,这是为什么呢?下面附源码两张:

  

  

  第一张图说明一级缓存直接在executor中活动,即作用范围为session;第二张图说明二级缓存在MappedStatement中活动,作用范围跨session了。同样证实了开篇提到的cache作用范围。也因为二级缓存的作用范围跨session,可以同时被多个session同时获取就出现了线程安全的问题,导致脏读问题。为了解决这一问题,就有了TransactionalCache及其Manager——就是tcm对应类。

  

  从其类图中,可以直观的发现其增加了读写锁相关的功能。

MyBatis功能点一:二级缓存cache的更多相关文章

  1. mybatis 使用redis实现二级缓存(spring boot)

    mybatis 自定义redis做二级缓存 前言 如果关注功能实现,可以直接看功能实现部分 何时使用二级缓存 一个宗旨---不常变的稳定而常用的 一级是默认开启的sqlsession级别的. 只在单表 ...

  2. Mybatis整合Redis实现二级缓存

    Mybatis集成ehcache . 为什么需要缓存 拉高程序的性能 . 什么样的数据需要缓存 很少被修改或根本不改的数据 业务场景比如:耗时较高的统计分析sql.电话账单查询sql等 . ehcac ...

  3. mybatis精讲(六)--二级缓存

    目录 简介 配置 源码 CachingExecutor 自定义二级缓存 # 加入战队 微信公众号 简介 上一章节我们简单了解了二级缓存的配置.今天我们详细分析下二级缓存以及为什么不建议使用二级缓存. ...

  4. myBatis源码解析-二级缓存的实现方式

    1. 前言 前面近一个月去写自己的mybatis框架了,对mybatis源码分析止步不前,此文继续前面的文章.开始分析mybatis一,二级缓存的实现.附上自己的项目github地址:https:// ...

  5. SSM+redis整合(mybatis整合redis做二级缓存)

    SSM:是Spring+Struts+Mybatis ,另外还使用了PageHelper 前言: 这里主要是利用redis去做mybatis的二级缓存,mybaits映射文件中所有的select都会刷 ...

  6. java:Mybatis框架3(二级缓存,延时和积极加载,SSI(Ibatis)集成,SSM集成)

    1.二级缓存: 需要导入二级缓存jar包: mybatis03: ehcache.xml: <ehcache xmlns:xsi="http://www.w3.org/2001/XML ...

  7. Mybatis架构原理(二)-二级缓存源码剖析

    Mybatis架构原理(二)-二级缓存源码剖析 二级缓存构建在一级缓存之上,在收到查询请求时,Mybatis首先会查询二级缓存,若二级缓存没有命中,再去查询一级缓存,一级缓存没有,在查询数据库; 二级 ...

  8. mybatis结合redis实战二级缓存(六)

    之前的文章中我们意见分析了一级缓存.二级缓存的相关源码和基本原理,今天我们来分享下了mybatis二级缓存和redis的结合,当然mybatis二级缓存也可以和ehcache.memcache.OSC ...

  9. SpringMVC + MyBatis + Mysql + Redis(作为二级缓存) 配置

    2016年03月03日 10:37:47 标签: mysql / redis / mybatis / spring mvc / spring 33805 项目环境: 在SpringMVC + MyBa ...

随机推荐

  1. HDU-1004(C语言描述)

    Let the Balloon Rise 输入 输入包含多个测试用例.每个测试用例都以数字 N (0 < N < = 1000) 为起点, 分布的气球总数.下 N 行包含一个颜色.气球的颜 ...

  2. 关于 Intel CPU 和Iris Xe Graphics的报告问题

    关于 Intel CPU 和Iris Xe Graphics的报告问题 有些用户报告了一些技术问题,这里有更多的信息和如何解决. Intel 11th CPU & Iris Xe Graphi ...

  3. MMI开机时间偏长

      Mini版本开机时间长 Mini版本开机时间长1. Problem Description:2. Analysis:3. Solution:4. Summary: 1. Problem Descr ...

  4. 【Java常用类】DateTimeFormatter

    DateTimeFormatter 方式一:预定义的标准格式 实例化 如:ISO_LOCAL_DATE_TIME;ISO_LOCAL_DATE;ISO_LOCAL_TIME DateTimeForma ...

  5. Solon Web 开发,一、开始

    Solon Web 开发 一.开始 二.开发知识准备 三.打包与运行 四.请求上下文 五.数据访问.事务与缓存应用 六.过滤器.处理.拦截器 七.视图模板与Mvc注解 八.校验.及定制与扩展 九.跨域 ...

  6. 【记录一个问题】thanos receiver在更换tsdb文件后,内存并未显著下降

    在16:14,切换了TSDB 在16::15分切换了TSDB,并且上游未写入数据 容器的内存并未在这个时刻明显下降 疑惑: 如果thanos receiver的内存占用不与time series数量正 ...

  7. manjaro20WPS缺少字体

    宋体等 sudo pacman -S ttf-wps-fonts Ariel和Times New Roman https://askubuntu.com/questions/651441/how-to ...

  8. Cesium中文网的朋友们

    目前已开通知识星球-Cesium中文网的朋友们 注意:仔细思量好再进来,一旦付费,概不退费.下述内容均尽力而为. 1. 每月一次技术交流(Cesium为主),提供源码. 2. 每人5次/周免费提问(C ...

  9. 513. Find Bottom Left Tree Value

    Given a binary tree, find the leftmost value in the last row of the tree. Example 1: Input: 2 / \ 1 ...

  10. Qt之消息对话框

    widget.h: #ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include<QLineEdit> class ...