mybatis源码分析之走进缓存
之前写了一篇关于mybatis缓存的读后感,想了想还是把缓存模块简单分析一下,附赠下载地址:https://github.com/MyBatis/MyBatis-3,github直接搜排名很靠前的。
先看一张缓存源码包图片:

其实看到这个包,大致可以猜出decorators是装饰器,Cache是缓存的抽象,PerpetualCache类是缓存的具体实现,TransactionalCacheManager应该是关于事务的处理,带着这些猜测首先看下Cache类的源码实现:

可以看到里面都是关于缓存的增删改查操作以及读写锁的支持,但是都是抽象方法,接下来我们可以具体看下我们之前猜测的实现类PerpetualCache:

从红色框标注的看到确实是实现了cache接口的,实现的也很简单,只是使用了HashMap作为缓存容器,以及对map的基本操作。看到这里,是不是觉得这实现的也太简单了吧,而且,这个读写锁return null是什么鬼。我们首先来看是不是真的只是对hashMap的简单操作,回到最上面的图可以看到有一个cacheKey不知道是干什么的,先点进去看看里面写了啥:

进到代码里可以看到有几个核心的参数:

那么这些参数到底是怎么进行操作的呢,我们看一下里面核心的两个方法update和equals:


update方法其实就是通过计算hash值以及简单的运算更新参数,感兴趣的可以仔细研究测试一下,主要目的是为了减少key的冲突,equals则主要根据参数值的对比判断是否是同一个cacheKey,任意点开一个调用update方法的地方:

其实就是sql,节点id,分页信息以及参数信息,对多个值重复计算更新cachekey属性以尽量避免冲突,看到这我们是不是可以想到一个问题,只要nameSpace+分页+sql+参数都一样的话那就是同一个缓存值,哦,确实,都一样的话肯定是同一个。看到这里mybatis的缓存设计的是不是还是有点意思的,但是之前听说mybatis缓存模块设计的挺优雅的,就这样逼格还行但是也算不上优雅吧,我们发现还有一个包里面我们一个都没看过,打开decorators包发现里面都是实现了Cache接口的装饰器,这些装饰器的构造器都是需要传入一个缓存实现的,那么很明显,都是在最基础的PerpetualCache缓存基础上做的装饰而已。
BlockingCache:
首先看一下的get put方法:

可以看出其实就是阻塞版本的缓存装饰器,保证只有一个线程到数据库去查找指定的key对应的数据,而阻塞的实现就是使用可重入锁ReentrantLock控制并发。
FifoCache:

使用linkedList做先进先出的队列。
LoggingCache:

其实也就是在查询之后打印日志。
LruCache:

使用LinkedList实现热点访问。
ScheduledCache:

在每次读写时都会去删除过时的缓存,达到缓存的定时失效。
SerializedCache:


序列化缓存值,每次写入都会先进行序列化操作,读出都会反序列化。
SoftCache:

使用软引用存储缓存value值,若被垃圾回收器回收,则从容器中删除。
SynchronizedCache:

这个就很简单,加synchronized关键字,保证线程安全,这也是为什么二级缓存明明是跨sqlSession的,但是使用hashMap就可以保证线程安全。
TransactionalCache:添加事务处理。
WeakCache:和上面的软引用一样,只不过弱引用包装value值。
ps:软引用是表示垃圾回收器回收的时候,内存不够用才会回收,而弱引用在垃圾回收器回收的时候,无论什么状态,都会将对象回收。
上面其实就是mybatis缓存模块大致的运行机制与实现,还写了一篇文章简单聊了读完mybatis缓存源码,对缓存机制嗯大理解以及使用:https://www.cnblogs.com/gmt-hao/p/12317600.html欢迎大家指教。
mybatis源码分析之走进缓存的更多相关文章
- Mybatis 源码分析之一二级缓存
一级缓存 其实关于 Mybatis 的一级缓存是比较抽象的,并没有什么特别的配置,都是在代码中体现出来的. 当调用 Configuration 的 newExecutor 方法来创建 executor ...
- MyBatis 源码分析 - 缓存原理
1.简介 在 Web 应用中,缓存是必不可少的组件.通常我们都会用 Redis 或 memcached 等缓存中间件,拦截大量奔向数据库的请求,减轻数据库压力.作为一个重要的组件,MyBatis 自然 ...
- Mybatis源码分析之Cache二级缓存原理 (五)
一:Cache类的介绍 讲解缓存之前我们需要先了解一下Cache接口以及实现MyBatis定义了一个org.apache.ibatis.cache.Cache接口作为其Cache提供者的SPI(Ser ...
- mybatis源码分析之06二级缓存
上一篇整合redis框架作为mybatis的二级缓存, 该篇从源码角度去分析mybatis是如何做到的. 通过上一篇文章知道,整合redis时需要在FemaleMapper.xml中添加如下配置 &l ...
- MyBatis源码分析-SQL语句执行的完整流程
MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以对配置和原生Map使用简 ...
- MyBatis源码分析(5)——内置DataSource实现
@(MyBatis)[DataSource] MyBatis源码分析(5)--内置DataSource实现 MyBatis内置了两个DataSource的实现:UnpooledDataSource,该 ...
- MyBatis源码分析(4)—— Cache构建以及应用
@(MyBatis)[Cache] MyBatis源码分析--Cache构建以及应用 SqlSession使用缓存流程 如果开启了二级缓存,而Executor会使用CachingExecutor来装饰 ...
- MyBatis源码分析(3)—— Cache接口以及实现
@(MyBatis)[Cache] MyBatis源码分析--Cache接口以及实现 Cache接口 MyBatis中的Cache以SPI实现,给需要集成其它Cache或者自定义Cache提供了接口. ...
- 【MyBatis源码分析】select源码分析及小结
示例代码 之前的文章说过,对于MyBatis来说insert.update.delete是一组的,因为对于MyBatis来说它们都是update:select是一组的,因为对于MyBatis来说它就是 ...
随机推荐
- Spring Boot GraphQL 实战 01_快速入门
hello,大家好,我是小黑,又和大家见面啦~ 新开一个专题是关于 GraphQL 的相关内容,主要是通过 Spring Boot 来快速开发 GraphQL 应用,希望对刚接触 GraphQL 的同 ...
- canvas可视化效果之内阴影效果
canvas可视化效果之内阴影效果 楔子 在之前的一个轨道交通可视化项目中,运用到了很多绘制技巧. 可以参考 之前的一篇文章 <利用canvas阴影功能与双线技巧绘制轨道交通大屏项目效果> ...
- python一键搭建ftp服务
from pyftpdlib.authorizers import DummyAuthorizer from pyftpdlib.handlers import FTPHandler from pyf ...
- Asp.net Core3.1+Vue 使用SignalR推送数据
本文就简单使用 往前端页面推送消息 SignalR 是什么 SignalR是一个.NET Core/.NET Framework的开源实时框架. SignalR的可使用Web Socket, Serv ...
- python序列(一)列表的增加
列表是python中内置有序可变序列,列表的所有元素放在一堆中括号"{}"中,并使用逗号隔开 1.列表的创建 使用"="直接创建一个列表 >>> ...
- Gitlab+Jenkins构建一个Go项目
部署Go项目简介 对于golang的发布,之前一直没有一套规范的发布流程,来看看之前发布流程: 方案一 • 开发者本地环境需要将环境变量文件改为正式环境配置 • 编译成可执行文件 • 发送给运维 • ...
- Linux下删除文件名带有空格的文件
1.使用单引号将文件名括起来进行操作: rm '2018-08-07 17-29-48.png'
- [leetcode]200. Number of Islands岛屿数量
dfs的第一题 被边界和0包围的1才是岛屿,问题就是分理出连续的1 思路是遍历数组数岛屿,dfs四个方向,遇到1后把周围连续的1置零,代表一个岛屿. /* 思路是:遍历二维数组,遇到1就把周围连续的1 ...
- Linux服务器上搭建测试环境(war包+tomcat)
悟空CRM项目环境部署(Java war项目) 在/root目录下创建一个文件夹(名字自取). ls命令查看一下是否创建成功,看到了新建的文件夹说明创建成功. tomcat和war包的准备:可以使用X ...
- IDEA关联mysql失败Server returns invalid timezone. Go to 'Advanced' tab and set 'serverTimezon'
时区错误,MySQL默认的时区是UTC时区 要修改mysql的时长 在mysql的命令模式下,输入: set global time_zone='+8:00'; 再次连接成功