文章目录

  • 一、执行器在什么位置
  • 二、执行器生成源码解析
    • 2.1、生成默认执行器
  • 三、执行器的结构分析
  • 四、完整查询分析
    • 4.1、二级缓存
    • 4.2、一级缓存
    • 4.3、数据库查询
    • 4.4、大致执行结构图
  • 五、手写代码还原基本骨架

本文大部分代码来自MyBatis源码,你可以对照着源码一起看

一、执行器在什么位置

初学MyBatis时,我们都知道MyBatis是拥有一级和二级两种缓存,并且默认开启一级缓存,二级缓存我们只需要在映射文件中手动配置即可。

<!--开启全局缓存,默认是开启的MyBatis-config.xml-->
<setting name="cacheEnabled" value="true"/><!-- XXXmapper.xml-->
<cache/>

补充一张我初学MyBatis时的图:

此处直接略过缓存相关的特性…

这里主要谈一点,就是我们学习MyBatis时常说的:SQL查询的顺序是,先二级缓存找,再一级缓存找,还是没有,最后再去数据库中查找

那么为什么呢?它背后是怎样利用代码完成的呢?

这里就要引入本文的主角——执行器(Executor)。多线程阶段学习时,也有一个执行器,当然我们这里所说的是MyBatis中的执行器。

基本的查询代码:

public class Demo01 {public static void main(String[] args) throws IOException {//1.根据配置文件构建sqlSessionFactoryString resource = "resources/mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//2.通过sqlSessionFactory构建SqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();//3.执行对应的SQLsqlSession.selectOne("org.apache.ibatis.demo.dao.BlogMapper.selectBlog");//4.关闭资源sqlSession.close();}
}

执行器在第二步生成

//2.通过sqlSessionFactory构建SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
  • 执行器提供了查询,修改,提交事务,回滚事务,清理一级缓存,FlashStatement接口。
  • 一个执行器对应一个SqlSession,由Configuration创建
  • 它和SQL处理器是一对多的关系

二、执行器生成源码解析

SqlSessionFactory 接口方法

public interface SqlSessionFactory {//默认SqlSession openSession();SqlSession openSession(boolean autoCommit);SqlSession openSession(Connection connection);SqlSession openSession(TransactionIsolationLevel level);//设置指定类型执行器SqlSession openSession(ExecutorType execType);SqlSession openSession(ExecutorType execType, boolean autoCommit);SqlSession openSession(ExecutorType execType, TransactionIsolationLevel level);SqlSession openSession(ExecutorType execType, Connection connection);Configuration getConfiguration();}

这是SqlSessionFactory接口,就执行器部分的讲解,我们可以将接口中的方法分为3类

  • 默认方法
  • 手动设置执行器类型
  • 其他方法

顺便补充执行器的类型:即我们能够设置的执行器的类型参数,是来自下面的枚举类。从这个枚举类可以看出,我们有三种执行器

public enum ExecutorType {//MyBatis有三种执行器,分别是:简单、复用、批量处理。默认使用简单的,来一条处理一条SIMPLE, REUSE, BATCH
}

2.1、生成默认执行器

public class Configuration {...protected ExecutorType defaultExecutorType = ExecutorType.SIMPLE;...public ExecutorType getDefaultExecutorType() {return defaultExecutorType;}
}

使用Configuration类中的默认值,作为我们执行器类型,即简单执行器是我们的默认执行器

拥有默认参数后的后续操作



如果我们需要生成其他的执行器,传入不同参数即可。

然后把生成的执行器作为参数放入到我们的CachingExecutor中,初始化delegate参数

这里先记牢,delegate这个参数的值是我们生成的真实的执行器,后文还会出现

至此,一个被CachingExecutor包裹着的SimpleExecutor创建完成


三、执行器的结构分析

我们已经看到执行器是如何产生的了,接下来就是本文的重点,执行器之间的关系,以及他们和缓存结构之间的联系。

这里涉及的类或接口共6个,先说结论:

  • 最底层的三个子类,分别是我们的批量执行器、简单执行器、复用执行器
  • BaseExecutor中包含一级缓存的查询,不包含真实的数据库中的查询
  • CachingExecutor中包含二级缓存,通过delegate变量延展
  • 每个类只完成一件事情

我们都知道,想要查询数据,我们可以直接去数据库中查询,但是总是进行磁盘IO十分影响效率,所以引出缓存查询。由于不同执行器去缓存中查询特性相同,我们就可以把这部分代码抽取出来,放到BaseExecutor抽象父类中。时间久了由于缓存的局限性,我们又引入了一个级别的缓存,并且称它为——二级缓存。MyBatis的开发者使用一个装饰者模式,让两者衔接起来。

我有想过为什么一定要这样写呢?写一个父类,不也可以?


四、完整查询分析

第二步已经生成了对应的执行器,现在我们需要开始执行对应的SQL查询

// 3.执行对应的SQ
sqlSession.selectList("org.apache.ibatis.demo.dao.BlogMapper.selectBlog");

我们调用的selectList方法,他们根据我们传入的参数的多少,不断完善默认值,最终执行query方法。

4.1、二级缓存

我们会发现,这个query方法是有两个实现类。

根据执行器生成的过程我们可以明确,此时我们会进入CachingExecutor,因为我们的执行器是一个被CachingExecutor包裹着的SimpleExecutor

前文让你牢记的delegate变量,这里出现了。她是在创建基本的执行器成功时,将自己作为参数放入到CachingExecutor中完成赋值的。即默认情况下,这里的delegate就是new SimpleExecutor()

4.2、一级缓存

第二节分析执行器结构时,说到基本的执行器都有一个公共的父类BaseExecutor,所以我们这里虽然调用的简单执行器,但是会先经过父类的查询方法,自然父类中就可以完成我们的一级缓存的查询。

4.3、数据库查询

自此,我们两重缓存的执行流程已经都走完了,接下来就是去简单执行器中查询对应的SQL。当然如果我们在前面的任何一级缓存中能查询到对应的数据,那么此次查询就会提前返回



4.4、大致执行结构图


五、手写代码还原基本骨架

手写一个测试类,完成上述查询的基本功能,具体代码如下:

浅析MyBatis执行器原理相关推荐

  1. 面试官:你分析过mybatis工作原理吗?

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 Mybatis工作原理也是面试的一大考点,必须要对其非常清晰,这样 ...

  2. 从源码角度分析 Mybatis 工作原理

    作者:vivo互联网服务器团队-Zhang Peng 一.MyBatis 完整示例 这里,我将以一个入门级的示例来演示 MyBatis 是如何工作的. 注:本文后面章节中的原理.源码部分也将基于这个示 ...

  3. Mybatis底层原理学习(二):从源码角度分析一次查询操作过程

    在阅读这篇文章之前,建议先阅读一下我之前写的两篇文章,对理解这篇文章很有帮助,特别是Mybatis新手: 写给mybatis小白的入门指南 mybatis底层原理学习(一):SqlSessionFac ...

  4. MyBatis运行原理(二)SqlSession对象创建过程分析

    PS:这篇博文承接上一篇: MyBatis运行原理(一)SqlSessionFactory对象创建过程分析 在上一篇博文中分析了SqlSessionFactory对象创建的过程,有了SqlSessio ...

  5. MyBatis(四)MyBatis插件原理

    MyBatis插件原理 MyBatis对开发者非常友好,它通过提供插件机制,让我们可以根据自己的需要去增强MyBatis的功能.其底层是使用了代理模式+责任链模式 MyBatis官方https://m ...

  6. mybatis返回null_面试官:你分析过mybatis工作原理吗?

    Mybatis工作原理也是面试的一大考点,必须要对其非常清晰,这样才能怼回去.本文建立在Spring+SpringMVC+Mybatis整合的项目之上. 我将其工作原理分为六个部分: 读取核心配置文件 ...

  7. mybatis工作原理_万字好文!MyBatis 的工作原理,你了解过吗?

    回复 1024 有特别礼包 作者:江南入直 | 来源:cnblogs.com/scuury/p/10371246.html 上一篇:微信支付的架构到底有多牛? 近来想写一个mybatis的分页插件,但 ...

  8. MyBatis 实现多表查询、resultMap 标签、MyBatis 注解、mybatis运行原理

    内容 Auto Mapping 单表实现(别名方式) 实现单表配置 单个对象关联查询(N+1,外连接) 集合对象关联查询 注解开发 MyBatis 运行原理 一.MyBatis 实现多表查询 Myba ...

  9. MyBatis的原理

    MyBatis是一款常用的持久层框架,它支持定制化的SQL.存储过程以及高映射.MyBatis封装了JDBC的代码,可以简单的使用XML或注解来配置和映射原生信息,将接口和Java的普通对象映射成数据 ...

  10. Mybatis运行原理及源码解析

    Mybatis源码解析 一.前言 本文旨在mybatis源码解析,将整个mybatis运行原理讲解清楚,本文代码地址: https://github.com/lchpersonal/mybatis-l ...

最新文章

  1. UnicodeEncodeError: ‘locale‘ codec can‘t encode character ‘\u5e74‘ in position 2: Illegal byte seque
  2. 我是如何学习写一个操作系统(三):操作系统的启动之保护模式
  3. LeetCode:位运算实现加法
  4. swift基础学习(八)
  5. Python 使用ntplib库同步校准当地时间的方法 (NTP)
  6. lightbox的一个ajax效果
  7. 收集:Hibernate中常见问题 No row with the given identifier exists问题的原因及解决
  8. 【HDU5869】Different GCD Subarray Query(求[L,R]内有多少个不同的区间gcd---树状数组+思维)
  9. 梦游计算机,传承与奉献!《梦幻西游》电脑版《梦游敦煌》完结
  10. 伊朗 2018 ICPC区域赛 A : Iranian ChamPions Cup
  11. 【软考】PV操作同步互斥
  12. 关于我的专业(niit软件工程方向)
  13. webERP安装配置超详细
  14. 02-leveldb入门
  15. 软件测试方法和测试策略
  16. Python爬虫抓取东方财富网股票数据并实现MySQL数据库存储
  17. 【ospf路由计算(一类LSA-router、二类LSA-Network、三类LSA-sum-Net)】-20211228-30
  18. SMC压缩空气质量分级及管理——含水量篇
  19. 信号与系统难点之采样正弦信号的获取问题
  20. 浏览器调取摄像头拍照并有遮罩层

热门文章

  1. CF1A Theatre Square
  2. mysql查询季度数据统计_mysql按年度、季度、月度、周、日SQL统计查询代码
  3. 电脑中的打印驱动程序如何打包_旧驱动程序会教您如何处理笔记本电脑上的黑屏...
  4. linux备份文件_aptclone:备份已安装的软件包并在新的 Ubuntu 系统上恢复它们 | Linux 中国...
  5. html行为样式动作是啥,什么是结构、样式、行为分离?
  6. 生活中常见物联网实例_包邮赠书| 什么是物联网?常见IoT 物联网协议最全讲解...
  7. java recv failed,java.sql.SQLException: I/O Error: Software caused connection abort: recv failed
  8. labview 判断整数_labview教程——如何判断字符串包含的是数字
  9. mysql master slave模式,mysql复制(Replication)模式 主从(Master Slave)模式
  10. 程序员必备的css工具,8个提高效率的CSS实用工具