| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> Java知识库 -> Mybatis二级缓存源码剖析 -> 正文阅读 |
|
[Java知识库]Mybatis二级缓存源码剖析 |
?级缓存构建在?级缓存之上,在收到查询请求时,MyBatis 首先查询?级缓存,若?级缓存未命 中,再去查询?级缓存,?级缓存没有,再查询数据库。 与?级缓存不同,?级缓存和具体的命名空间绑定,?个Mapper中有?个Cache,相同Mapper中的 MappedStatement公用?个Cache,?级缓存则是和 SqlSession 绑定 一,全局二级缓存开启配置
方向:通过配置开启二级缓存,源码剖析从配置读取生效入手 还是如同Mybatis之前的解析步骤一样,从Mybatis初始化读取配置入手,进入到XMLConfigureBuilder类中的parse方法。 然后继续往下层去剥,根据上面的开启全局二级缓存配置,找到parseConfiguration中的解析Setting标签的部分。 ?二,Mapper中的Cache标签解析与对象构建全局二级缓存开启之后,对于使用二级缓存的Mapper.xml需要在Mapper标签内进行如下的配置: <cache></cache>。 从配置中可以知道,二级缓存绑定Mapper,真正去调用绑定应该还是在Mapper标签解析的时候去执行的。承接上面的解析代码进到mapperElement方法当中去,然后判断是指根据何种方式去读取的Mapper配置加载方式。读取的方式不会决定Mapper读取后处理的步骤,这里从路径配置的else条件中parse方法进入。 ?一直往下走到这里为止,则看到了Mapper解析时,解析cache标签的地方了。上面的cache-ref表示的是从别的地方去取缓存数据,这里不做多的深入探究,继续看cacheElement方法。 ?进到cacheElement中后,可以看到对于cache标签,还提供了其它的属性配置。?上面部分的属性配置读取完成后,最后useNewCache则开始创建Cache对象,点进去看如何去构建的。 ?进入到方法后,第一步实例化一个Cache对象,把之前的配置信息放入到对象中。然后第二步,是否是似曾相识?把构建好的Cache对象存入到Configuration对象当中去。之前的解析主线源码的时候有说过这个对象,解析出来的内容放入到Configuration对象然后一直向下传递。第三步则是把构建的新的二级缓存对象复制给buildAssistant类中的currentCache。 ?到这里为止,可以发现对于一个Mapper Cache对象只在初始化时候创建一次,符合?个Mapper中有?个Cache对象。但是相同的Mapper中公用一个Cache对象,之前主线源码解析有说过Mapper对象在解析后会整合了存入到Configuration中的MappeStatement容器中去,那么对于相同的Mapper读取整合后,Cache对象是否应该去绑定进去? 回到之前Mapper解析的方法中去,从buildStatementFromContext方法进去,这个方法之前有提到过,对于整合解析好的Mapper会存入到MappeStatement当中去。然后对于判断不论如何都会去调用buildStatementFromContext方法,直接点进该方法。 ?然后看到又构建了一个XMLBuilder,然后去解析MappeStatement,这里的代码之前主线解析也有提到过。进入到parseStatementNode方法,重要看关于cache的部分,之前该方法的完整部分也有在主线解析时贴出来,这里直接看重点的几行代码。 flushCache都不陌生,对于每次数据库操作是否都去刷新当前缓存,后面的useCache则是是否使用二级缓存. 然后该方法往下拉,到构建MappeStatement,注意这里的对象buildAssistant,上面有提到过该对象,对于创建的Cache对象第三步,会赋值给buildAssistant类中的currentCache。 ?进入到该方法之后,对于之前的CurrentCache对象,会在MappeStatement构建的过程中进行绑定。?到这里位置Cache标签的解析,Cache对象的构建,传入与绑定则全部剖析完成。 三,二级缓存执行流程剖析SQL执行的过程中如何从二级缓存中存入和拿取数据?既然涉及了SQL的执行,那么从直接从SqlSession中的常用数据操作方法入手,这里就从SqlSession中的SelectList入手。(为什么不从selectOne?selectOne底层也是并入到selectList中去委派Excutor执行的) ?通过Debug模式可以发现,在开启了二级缓存后,executor的执行方式和之前主线源码解析的不同了,它会跳转到CachingExecutor中去委派执行SQL操作。 ?进入到CachingExecutor中的query方法,BoundSql对于参数#{}与?的转换,参数的传入,之前主线代码解析有提到过,这里不多做分析,这里创建了一个CacheKey,然后去执行查询的操作。 ?进入到query方法后,注意几个方面: 1,cache标签上面解析最后的步骤时,会对于MappedStatement进行绑定,确定相同的MappeStatement公用一个Cache对象,这里从MappedStatement中获取Cache对象 2,上面有提到过的Cache标签中还能够去配置的一些参数,比如是否有用到二级缓存的UseCache,Mapper解析时,是否每次操作都要清空缓存的数据flushCache。 3,这里的tcm是一个二级缓存的事务管理器,它的作用就是从二级缓存的中去取数据,因为是第一次操作,list肯定是空的,那么走到下面的delegate 4,delegate可以看到是一个excutor,它负责去执行做SQL操作,这里的executor通过Debug去执行,会发现它跳转到了BaseExecutor中去,如同主线执行一样,会从一级缓存中去拿结果。 ?但是第一次执行肯定一级缓存中也没有数据,那么则会从数据库中去拿数据,然后存入到本地缓存,也就是所谓的一级缓存。 ?数据存入到了一级缓存中了,上面的代码中有这样一个存放数据的操作,这个操作时进行二级缓存吗? 点进去后到TransactionalCacheManager对象,对象中对Cache作为Key去再封装了一层,这里为什么不直接使用Cache对象呢?Cache对象在一个MappeStatement中的唯一性,如果直接获取,多请求并发时会导致线程的不安全性,所以把缓存的数据放入到了一个TransactionCache中去。 ?继续往下走,到TransactionalCache对象中,这里把查询的数据存入到了该对象的Set集合中,那么问题来了,到这里为止,数据都没有存入到二级缓存中去,这里的存入到Set中是因为事务性,回滚操作下防止二级缓存的频繁存取。 在TransactionalCache中可以看到commit方法,二级缓存只对提交的事务会写入。commit中,delegate是否似曾相识?之前二级缓存的获取,就是从tcm的get方法,就从这里获取的,它就是一个二级缓存的对象。 ?然后去看flushPendingEntries方法,entriesToAddOnCommit这个容器已经提到过了,这里从容器中获取未提交的容器中的数据存入到二级缓存。到这里为止,可以发现二级缓存对于没有提交的数据是不具备缓存作用的,如果没有提交,delegate缓存对象永远是一个null值,永远拿不到数据。 四,二级缓存的刷新机制?二级缓存的刷新无非在于SQL进增删改操作时的缓处理。还是SqlSession当中去,去看非查询的操作,这里从更新操作着手。还是会判断update标签中是否加入了flushCache属性。update操作之前都会去执行一次select操作,第一次执行flush方法时候,利用debug跟踪,因为下面的参数为false不会去清空二级缓存,但是在查询之后会对该参数重新赋值为true,在第二次执行时,这里的判断就是true了,则会情空二级缓存。 然后继续往下走,到BaseExecutor中去,到这里更新完会清空本地的缓存数据,也就是一级缓存的数据,然后执行doUpdate方法完成更新。 ? |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/23 9:17:13- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |