我们知道mybatis通过门面模式给我们提供了一个统一的增删改查的会话SqlSession。但是呢它就像服务员一样只负责点菜并不负责做菜,真正做菜的是执行器。那mybatis中有哪些执行器呢?

mybatis中的执行器大概有这么多:Executor、CachingExecutor、BaseExecutor、SimpleExecutor、ReuseExecutor、BatchExecutor等。看起来好像很多其实很简单,咱们往下走。

我们通过最简单的一个查询来看看这些货到底是什么关系:

List<Object> list = sqlSession.selectList("select * from t ");

sqlSession默认实现是DefaultSqlSession,所以我们进到这个方法:

public <E> List<E> selectList(String statement) {return this.selectList(statement, (Object)null);}

继续进到这个方法:

public <E> List<E> selectList(String statement, Object parameter) {return this.selectList(statement, parameter, RowBounds.DEFAULT);}

继续:

public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {List var5;try {MappedStatement ms = this.configuration.getMappedStatement(statement);//注意 这里真正干活的是this.executor 而这个executor默认实现是CachingExecutorvar5 = this.executor.query(ms, this.wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER);} catch (Exception var9) {throw ExceptionFactory.wrapException("Error querying database.  Cause: " + var9, var9);} finally {ErrorContext.instance().reset();}return var5;}

至此,我们知道了真正干活的是这个CachingExecutor。顾名思义这是个缓存相关的执行器,它就是大名鼎鼎的二级缓存执行器。里边实现了mybatis的二级缓存相关实现。但是本篇文章并不详细解释。我们进到CachingExecutor的query方法:

public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException {BoundSql boundSql = ms.getBoundSql(parameterObject);CacheKey key = this.createCacheKey(ms, parameterObject, rowBounds, boundSql);//进到这个重载方法return this.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);}

继续:

public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {Cache cache = ms.getCache();if (cache != null) {this.flushCacheIfRequired(ms);if (ms.isUseCache() && resultHandler == null) {this.ensureNoOutParams(ms, boundSql);//这里就是去查询二级缓存了List<E> list = (List)this.tcm.getObject(cache, key);if (list == null) {//如果没有查询到 那么就去执行this.delegate的query方法list = this.delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);this.tcm.putObject(cache, key, list);}return list;}}return this.delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);}

那么这个this.delegate是啥呢?它就是BaseExecutor,正式mybatis里边一级缓存的执行器。那么我们继续:

public <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {ErrorContext.instance().resource(ms.getResource()).activity("executing a query").object(ms.getId());if (this.closed) {throw new ExecutorException("Executor was closed.");} else {if (this.queryStack == 0 && ms.isFlushCacheRequired()) {this.clearLocalCache();}List list;try {++this.queryStack;//这里就是在查询一级缓存了list = resultHandler == null ? (List)this.localCache.getObject(key) : null;if (list != null) {this.handleLocallyCachedOutputParameters(ms, key, parameter, boundSql);} else {//如果没有查询到 那么就真正的去查询数据库了list = this.queryFromDatabase(ms, parameter, rowBounds, resultHandler, key, boundSql);}} finally {--this.queryStack;}if (this.queryStack == 0) {Iterator var8 = this.deferredLoads.iterator();while(var8.hasNext()) {DeferredLoad deferredLoad = (DeferredLoad)var8.next();deferredLoad.load();}this.deferredLoads.clear();if (this.configuration.getLocalCacheScope() == LocalCacheScope.STATEMENT) {this.clearLocalCache();}}return list;}}

我们继续进到queryFromDatabase方法:

private <E> List<E> queryFromDatabase(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {this.localCache.putObject(key, ExecutionPlaceholder.EXECUTION_PLACEHOLDER);List list;try {//进到这个方法list = this.doQuery(ms, parameter, rowBounds, resultHandler, boundSql);} finally {this.localCache.removeObject(key);}this.localCache.putObject(key, list);if (ms.getStatementType() == StatementType.CALLABLE) {this.localOutputParameterCache.putObject(key, parameter);}return list;}
protected abstract <E> List<E> doQuery(MappedStatement var1, Object var2, RowBounds var3, ResultHandler var4, BoundSql var5) throws SQLException;

我们发现,咦?咋是个抽象的方法呢?那么他的实现方法在哪儿呢?哈哈哈  BaseExecutor常用的有三个现实,正是SimpleExecutor ReuseExecutor BatchExecutor。通过名字也能看出来这个仨分别是简单 重用和批处理执行器。具体的操作数据库封装JDBC都是他们干的。行棋至此,我们mybatis中的执行器整体架构已经出来了,让我们画个图来总结一下吧!

mybatis源码分析系列(开胃菜)-mybatis中的执行器架构体系相关推荐

  1. MyBatis 源码分析系列文章合集

    1.简介 我从七月份开始阅读MyBatis源码,并在随后的40天内陆续更新了7篇文章.起初,我只是打算通过博客的形式进行分享.但在写作的过程中,发现要分析的代码太多,以至于文章篇幅特别大.在这7篇文章 ...

  2. MyBatis 源码分析系列文章导读

    1.本文速览 本篇文章是我为接下来的 MyBatis 源码分析系列文章写的一个导读文章.本篇文章从 MyBatis 是什么(what),为什么要使用(why),以及如何使用(how)等三个角度进行了说 ...

  3. MyBatis 源码分析系列文章导读 1

    1.本文速览 本篇文章是我为接下来的 MyBatis 源码分析系列文章写的一个导读文章.本篇文章从 MyBatis 是什么(what),为什么要使用(why),以及如何使用(how)等三个角度进行了说 ...

  4. MyBatis源码分析(一)MyBatis整体架构分析

    文章目录 系列文章索引 一.为什么要用MyBatis 1.原始JDBC的痛点 2.Hibernate 和 JPA 3.MyBatis的特点 4.MyBatis整体架构 5.MyBatis主要组件及其相 ...

  5. springboot集成mybatis源码分析-启动加载mybatis过程(二)

    springboot集成mybatis源码分析-启动加载mybatis过程(二) 1.springboot项目最核心的就是自动加载配置,该功能则依赖的是一个注解@SpringBootApplicati ...

  6. Mybatis源码分析(一)Mybatis 基本使用

    目录 一 知识回顾 1.1 简介 1.2 其他 二 基本使用 系列文章: 文章 状态 时间 描述 (一)Mybatis 基本使用 已复习 2022-12-14 对Mybtais的基本使用,能够开发 ( ...

  7. MyBatis 源码分析 - 插件机制

    1.简介 一般情况下,开源框架都会提供插件或其他形式的拓展点,供开发者自行拓展.这样的好处是显而易见的,一是增加了框架的灵活性.二是开发者可以结合实际需求,对框架进行拓展,使其能够更好的工作.以 My ...

  8. MyBatis 源码分析 - 缓存原理

    1.简介 在 Web 应用中,缓存是必不可少的组件.通常我们都会用 Redis 或 memcached 等缓存中间件,拦截大量奔向数据库的请求,减轻数据库压力.作为一个重要的组件,MyBatis 自然 ...

  9. MyBatis 源码分析 - 内置数据源

    1.简介 本篇文章将向大家介绍 MyBatis 内置数据源的实现逻辑.搞懂这些数据源的实现,可使大家对数据源有更深入的认识.同时在配置这些数据源时,也会更清楚每种属性的意义和用途.因此,如果大家想知其 ...

最新文章

  1. 清华系“AI帮”崛起,要驱动1500亿元产业规模
  2. linux fedor 安装 gcc,fedora中如何安装gccsense
  3. 深海中的STL—nth_element
  4. C# 命令行编译器详解
  5. PageRank算法以及Python实现(简洁版)
  6. mysql中explain的用法
  7. 项目管理实战之团队管理 (转)
  8. 长度最小的子数组--滑动窗口
  9. border三角形阴影(不规则图形阴影)和多重边框的制作
  10. 容器编排技术 -- Kubernetes kubectl delete 命令详解
  11. tuples_通过字典赋值
  12. linux下检查是否安装过某软件包
  13. Leetcode 刷题笔记(三) —— 数组类型解题方法三:滑动窗口
  14. Java SecureRandom 简单生成随机正整数
  15. KMP扩展KMPManacher算法基础与习题(第二更)
  16. 魔板(最小步数模型)
  17. 什么击计算机窗口可以打开资源管理器,Win8系统打开资源管理器窗口经常自动重启电脑解决措施...
  18. 一周信创舆情观察(1.24~2.6)
  19. JuiceFS分布式文件系统源码分析(Java层)
  20. 为何电脑下载mp3等音乐导入U盘后无法在汽车上播放?网易云等音乐软件夹带私货!!

热门文章

  1. c++ STL rope小结
  2. CP模式(ZK)的分布式锁分析
  3. 通过js来获取前天、昨天、今天、明天、后天、大后天的日期
  4. [Java]ResultSet的用法与实例
  5. HTML怎么设置超链接字体颜色和点击后的字体颜色?
  6. javascript速度_使用JavaScript设置视频播放速度
  7. 技术管理进阶——什么是管理者之体力、脑力、心力
  8. pyqt5界面右键菜单中文汉化(QLineEdit、QTextEdit)
  9. (要更新)N沟道和P沟道MOSFET
  10. A Review on Multi-Label Learning Algorithms.Min-Ling Zhang and Zhi-Hua Zhou(多标记学习算法综述,张敏灵,周志华)