这次我们来说说Mybatis的源码,这里只说执行的流程,内部细节太多了,这里只能授之以渔了。还是最近的那段代码,我们来回顾一下。

package mybatis;

import mybatis.bean.StudentBean;
import mybatis.dao.StudentMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test; import java.io.IOException;
import java.io.InputStream; public class Test1 { public SqlSession session;
public SqlSessionFactory sqlSessionFactory; @Before
public void init() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
session = sqlSessionFactory.openSession();
} @Test
public void studentTest() {
StudentMapper mapper = session.getMapper(StudentMapper.class);
StudentBean result = mapper.selectUser(1);
System.out.println(result);
session.commit();
} }

就是拿到流文件,也是我们主配置文件,进行流文件解析,传入到build内,构建成一个sqlSessionFactory,再由sqlSessionFactory得到session,拿到mapper,执行sql,完成。

简单的流程应该是这样的,我们来一个稍微专业一点图。

转变为我们的代码大概就是这三步,构建Configuration对象,构建我们的sqlsessionfactory,得到我们的session,得到对应的statement(处理参数和结果)从而得到结果集。

那么我们先从我们一步步来看,先看我们的Configuration对象

Configuration解析:

  我们打开Configuration类可以看到,里面很多的属性设置,包括缓存,mapper,插件等等,其实就是把我们的xml标签转化为对象了,这里需要说明一下的是,这个解析过程是把所有的相关的xml都转为Configuration对象了,包括config.xml和mapper.xml。源码太多,我就不粘贴了。我给你看一下我转化完成的。

这里没有什么神秘的,就是一个xml解析的过程,在XMLConfigBuilder类的parse方法,生成了完成的Configuration对象,有兴趣的可以打个断点看一下。

这里要注意的就是里面很多元素是一个对应多个的,很多属性是map和set。顺便收一下里面是由多个构造器来构建的。

MapperAnnotationBuilder为注解方式的构造器,其余都是为Configuration服务的。也就是说在创建Configuration之后很多东西就已经确定了(除了cache)。那么又是如何生成sqlsession的呢。回到我们创建完Configuration对象那句源码上来。

点击build方法进去,我们看到是new DefaultSqlSessionFactory然后把我们的Configuration对象传递进去,也就是说有了Configuration对象也就生成了我们的DefaultSqlSessionFactory对象。DefaultSqlSessionFactory实现了我们的SqlSessionFactory,我们也就得到了SqlSessionFactory。接下来就是我们的sqlsession了

sessionsql解析:

  还是老规矩,上个图再看源码,比较好理解。

执行过程大概是这样的。

 就是什么意思呢?由DefaultSqlSessionFactory生成一个执行器Executor,下面是由BaseExecutor支撑的,里面包含一些配置和我们的一级缓存(是不是更深入的知道为啥一级缓存生命短了),同时也有一个类似装饰器的CachingExecutor,他的下面也是需要BaseExecutor来支撑的,需要查询时优先查缓存,查询不到回到我们的BaseExecutor来执行。搂一眼源码去,sqlSessionFactory.openSession()方法也就得到了我们的sqlsession,我们进去看一下都写了什么。

里面的95行tx主要是从我们的configuration中拿到一些数据源的配置,也就是我们图中画的来支撑BaseExecutor的配置,来到96行,创建Executor,传入了数据源配置和一个执行类型,这里简单提一嘴,类型主要有三种:SIMPLE(简单), REUSE(可重复使用), BATCH(批量进行),一般我们都用的SIMPLE。我们再进我们的Executor的创建方法看看,他们都做了什么事。

先判断了执行器类型,简单,可重复,批量,613行就是我们的缓存执行器了,外面那个判断就是你是否配置了二级缓存,从而是否配置我们的缓存执行器,底层还是Executor,可以点击进去看看的。

就是说我们由配置文件config.xml,mapper.xml生成了我们的Configuration对象,将Configuration放置在DefaultSqlSessionFactory内,生成了我们的Executor执行器,准备执行SQL。回到主题我们继续看下一部分,最后一个MappedStatement

MappedStatement解析:

  记住两个问题,增删改查,可以归类为两种,一种是原来的数据变化-增删改,另一种是原来的数据没有变化-查询。我们的mybatis也是这样来处理的,主要就是query和update两种大类方法。

  MappedStatement是由调用Executor执行器前,由configuration对象来构建的。源码在DefaultSqlSession的select***方法内,这里就不详细说了。感兴趣的可以自己去了解一下。我们主要来说执行流程。

  执行过程大致是,1.拿到sql;2.拼接参数;3.执行sql;4.封装结果集。我们来看一下具体的源码流程。

  我们上面得知,执行器的真正执行都是在BaseExecutor里来执行的,我们在DefaultSqlSession调用的select方法,最后执行了executor.query,只优先走我们的CachingExecutor执行器,如果没有才到我们的BaseExecutor执行器里面来,我们的sql是查询,不需要变动数据,那么我们把断点打在我们的BaseExecutor类的query方法上。

147行是清理我们的一级缓存,如果在mapper.xml配置了清理标签,这里会先清理一级缓存。queryStack表示这个执行器是否正在被使用。

152行开始查询我们的一级缓存,如果为空调用156行,开始我们正式的查询,里面是放入缓存占位置,然后执行查询,清理缓存的占位重新放置缓存,这里说的都是一级缓存了。

总结一下就是:

1.拿到流文件config.xml和mapper.xml;

2.用我们的两个或多个流文件创建一个Configuration对象,(单一职责原则来构建的,很多个构造器来构建的,例如XMLConfigBuilder)

3.将Configuration对象塞给SqlSessionFactoryBuilder类的build方法,构建SqlSessionFactory对象。

4.sqlSessionFactory.openSession()拿到我们的session对象。

5.由session对象和Configuration对象封装参数和结果集映射,产生对应的执行器来,二级缓存执行器和BaseExecutor执行器。

6.由二级缓存执行器CachingExecutor来优先查询二级缓存是否存在,不存在执行BaseExecutor执行器的query或update方法。

7.拿到结果集转换ResultMap,session关闭,写入二级缓存,返回结束。

最进弄了一个公众号,小菜技术,欢迎大家的加入


java架构之路-(源码)mybatis执行流程源码解析的更多相关文章

  1. mybatis源码/mybatis执行流程源码解析

    https://www.cnblogs.com/cxiaocai/tag/%E9%9D%A2%E8%AF%95%E9%A2%98/public SqlSession session; public S ...

  2. Mybatis执行流程源码分析

    第一部分:项目结构 user_info表:只有id和username两个字段 User实体类: public class User { private String username; private ...

  3. [转帖]java架构之路-(面试篇)JVM虚拟机面试大全

    java架构之路-(面试篇)JVM虚拟机面试大全 https://www.cnblogs.com/cxiaocai/p/11634918.html   下文连接比较多啊,都是我过整理的博客,很多答案都 ...

  4. SpringMVC执行流程源码分析

    SpringMVC执行流程源码分析 我们先来看张图片,帮助我们理解整个流程 然后我们开始来解析 首先SpringMVC基于Servlet来运行 那么我们首先来看HttpServletBean这个类 他 ...

  5. java架构之路-(源码)mybatis基本使用

    我们今天先来简单了解一下我们持久层框架,mybatis的使用.而且现在的注解成为趋势,我主要说一下注解方向的使用吧(配置文件也会说) 从使用角度只要是三个部分,mybatis-config.xml,m ...

  6. java架构之路-(源码)mybatis的一二级缓存问题

    上次博客我们说了mybatis的基本使用,我们还捎带提到一下Mapper.xml中的select标签的useCache属性,这个就是设置是否存入二级缓存的. 回到我们正题,经常使用mybatis的小伙 ...

  7. java架构之路-(spring源码篇)由浅入深-spring实战详细使用

    今天我更新了一篇jvm垃圾回收的算法和垃圾回收器的内部逻辑,但是看的人不多啊......貌似大家还是比较喜欢看源码吧,毕竟实战要比理论用的多. 这篇文章不会详细的深入底层源码,只是基于注解和配置来说说 ...

  8. java架构之路-(SpringMVC篇)SpringMVC主要流程源码解析(上)源码执行流程

    做过web项目的小伙伴,对于SpringMVC,Struts2都是在熟悉不过了,再就是我们比较古老的servlet,我们先来复习一下我们的servlet生命周期. servlet生命周期 1)初始化阶 ...

  9. java架构之路-(spring源码篇)springIOC容器源码解析(上)

    我们这次来叭叭一下Spring的源码,这次博客主要来说说Spring源码,先粗略的撸一遍,下篇博客选几个重点去说,由于过于复杂,我也是看了一点点,我们先来过一遍源码,然后上流程图,最后我们再回头总结一 ...

随机推荐

  1. Java——标准异常

    Throwable这个java类被用来表示任何可以作为异常被抛出的类,Throwable可以分为两种类型,Error用来表示编译时和系统错误,Exception是可以被抛出的基本类型. 1.Runti ...

  2. Flutter 1.7 正式版发布

    今天,我们非常高兴地向大家宣布又一个正式版本的发布 -- Flutter 1.7,这是继上次 I/O 时众多重要功能发布以来的一次小更新.Flutter 1.7 包含了对 AndroidX 的支持,满 ...

  3. Spring Boot 中的同一个 Bug,竟然把我坑了两次!

    真是郁闷,不过这事又一次提醒我解决问题还是要根治,不能囫囵吞枣,否则相同的问题可能会以不同的形式出现,每次都得花时间去搞.刨根问底,一步到位,再遇到类似问题就可以分分钟解决了. 如果大家没看过松哥之前 ...

  4. 夯实Java基础(十七)——注解(Annotation)

    1.注解概述 从JDK5.0开始,Java增加对元数据(MetaData)的支持,也就是注解(Annotation).其实我们早就已经接触过注解了,例如我们经常在Java代码中可以看到 “@Overr ...

  5. mysql5.7绿色版配置以及找不到 mysql服务问题解决

    一.下载软件 1. 进入mysql官网,登陆自己的Oracle账号(没有账号的自己注册一个),下载Mysql-5.7.17,下载地址:http://dev.mysql.com/downloads/my ...

  6. LCA最近公共祖先---倍增法笔记

    先暂时把模板写出来,A几道题再来补充 此模板也是洛谷上的一道模板题 P3379 [模板]最近公共祖先(LCA) #pragma GCC optimize(2) //o2优化 #include < ...

  7. 腾讯PCG(后台开发) 牛客网视频面试 一面

    腾讯视频面试 作为一个小渣渣记录一下,腾讯是我一直想进的公司,但其实准备的时间不是很长,也不是科班还是存在很大的劣势,记录一下找工作的经历. 首先说一下,这是我第一次视频面试,还是蛮紧张的.不过面试官 ...

  8. Kafka 系列(五)—— 深入理解 Kafka 副本机制

    一.Kafka集群 Kafka 使用 Zookeeper 来维护集群成员 (brokers) 的信息.每个 broker 都有一个唯一标识 broker.id,用于标识自己在集群中的身份,可以在配置文 ...

  9. linux下搭建LJMT(图文版)

    一.  安装VM14 1.1 安装虚拟机vm14(略) 输入序列号:AC5XK-0ZD4H-088HP-9NQZV-ZG2R4(可自行百度) 二. 安装centos详细步骤 2.1安装centos.( ...

  10. 用 Python 分析上网记录,发现了很多不可思议的事

    摘要:分享个​ Python 神工具.​ 长时间使用浏览器会积累大量浏览器历史记录,这些是很隐私的数据,里面甚至可能有一些不可描述的网站或者搜索记录不想让别人知道. 不过,我们自己可能会感兴趣,天天上 ...