这是昨晚的武汉,晚上九点钟拍的,疫情又一次来袭,曾经熙熙攘攘的夜市也变得冷冷清清,但比前几周要好很多了。希望大家都能保护好自己,保护好身边的人,生活不可能像你想象的那么好,但也不会像你想象的那么糟。

好了,言归正传,搞技术的努力提升技术才是王道。

这是Mybatis 源码解析第三篇文章

①、Mybatis 源码解析1——从JDBC到Mybatis

②、Mybatis 源码解析2——从0到1实例搭建

在上一篇文章《Mybatis从0到1实例搭建》中,可乐给大家手撸了一遍如何通过 Mybatis 对数据库一张表进行增删改查。至此,Mybatis 的前奏已经演奏完毕,接下来,我们将会进入高潮部分,请大家搬好小板凳,可乐将会用最通俗易懂,图文并茂的方式,给大家深入剖析 Mybatis 的实现原理。

本篇文章我们首先解析 SqlSessionFactory 的创建过程。

1、实例代码

在实例代码中,我们在测试类中写了一个 init() 方法,里面包括了 SqlSessionFactory 的构建,分为两步。

第一步:读取配置文件 mybatis-config.xml 输入流

第二步:根据输入流构建 SqlSessionFactory;

public void init() {
    //定义mybatis全局配置文件
    String resource = "mybatis-config.xml";
    //加载 mybatis 全局配置文件
    InputStream inputStream = null;
    try {
        inputStream = Resources.getResourceAsStream(resource);
    } catch (IOException e) {
        e.printStackTrace();
    }
    //构建sqlSession的工厂
    sessionFactory = new SqlSessionFactoryBuilder().build(inputStream); }

没什么难的,去掉 try-catch,也就两行代码。

InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

是的,那只是你以为的两行代码,其实......

话不多说,可乐就来给大家揭秘这冰山下面的东西。

2、构建过程图示

大家可以先看可乐为大家总结的两张流程图。

温馨提示:结合流程图,再来服用代码,效果更佳。

3、代码剖析

根据上面的时序图,我们分析根据源码分析每个步骤。

①、获取配置文件输入流

InputStream inputStream = Resources.getResourceAsStream("mybatis.config.xml");

这里没什么好说的,就是获取配置文件的输入流。

②、build(in)

这里的 in 就是上一步获取的输入流 inputStream。

  public SqlSessionFactory build(InputStream inputStream) {
    return build(inputStream, null, null);
  }

在进入到 build 方法:

  public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
    try {
      XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
      return build(parser.parse());
    } catch (Exception e) {
      throw ExceptionFactory.wrapException("Error building SqlSession.", e);
    } finally {
      ErrorContext.instance().reset();
      try {
        inputStream.close();
      } catch (IOException e) {
        // Intentionally ignore. Prefer previous error.
      }
    }
  }

③、XMLConfigBuilder(in)

这一段代码是为了解析我们的配置文件,配置文件是 XML形式 ,我在之前的博客介绍过解析 XML 的几种方式。

一种是基于树的结构来解析的称为DOM;另一种是基于事件流的形式称为SAX和(StAX)

两者各有优缺点,我这里不做详细说明,想了解的可以看我之前的文章。

而 Mybatis 使用的是 DOM 形式,并结合 XPath 来解析配置文件。

④、parse()

    public Configuration parse() {
        if (this.parsed) {
            throw new BuilderException("Each XMLConfigBuilder can only be used once.");
        } else {
            this.parsed = true;
            this.parseConfiguration(this.parser.evalNode("/configuration"));
            return this.configuration;
        }
    }

从 /configuration 标签处开始解析。然后我们进入到 this.parseConfiguration() 方法中:

    private void parseConfiguration(XNode root) {
        try {
            this.propertiesElement(root.evalNode("properties"));
            Properties settings = this.settingsAsProperties(root.evalNode("settings"));
            this.loadCustomVfs(settings);
            this.loadCustomLogImpl(settings);
            this.typeAliasesElement(root.evalNode("typeAliases"));
            this.pluginElement(root.evalNode("plugins"));
            this.objectFactoryElement(root.evalNode("objectFactory"));
            this.objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
            this.reflectorFactoryElement(root.evalNode("reflectorFactory"));
            this.settingsElement(settings);
            this.environmentsElement(root.evalNode("environments"));
            this.databaseIdProviderElement(root.evalNode("databaseIdProvider"));
            this.typeHandlerElement(root.evalNode("typeHandlers"));
            this.mapperElement(root.evalNode("mappers"));
        } catch (Exception var3) {
            throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + var3, var3);
        }
    }

看到这是不是很熟悉了,这不就是mybatis-config.xml 配置文件里面的各个标签名嘛,是的,这就是解析该文件,然后全部放在 configuration 对象中。需要注意的是,这里的 configuration 对象不仅包括 mybatis-config.xml 文件内容,也包括 xxxMapper.xml 文件内容。

⑤、build(configuration)

  public SqlSessionFactory build(Configuration config) {
    return new DefaultSqlSessionFactory(config);
  }

就是去 new 了一个 DefaultSqlSessionFactory 对象,将 configuration 作为参数。

⑥、DefaultSqlSessionFactory(configuration)

    public DefaultSqlSessionFactory(Configuration configuration) {
        this.configuration = configuration;
    }

4、总结

自此,SqlSessionFactory 的创建过程就讲完了,总的来说就是一个封装了配置文件的工厂类。那么得到了 SqlSessionFactory 这个工厂对象,接下来干嘛?生产 SqlSession,然后通过 SqlSession 进行数据库的增删改查操作

没错,接下来,可乐将给大家介绍 SqlSession 的交互过程,这也是 Mybatis 里面最重要的一个对象。

Mybatis源码解析3——核心类SqlSessionFactory,看完我悟了的更多相关文章

  1. Mybatis源码解析(三) —— Mapper代理类的生成

    Mybatis源码解析(三) -- Mapper代理类的生成   在本系列第一篇文章已经讲述过在Mybatis-Spring项目中,是通过 MapperFactoryBean 的 getObject( ...

  2. Mybatis源码解析,一步一步从浅入深(六):映射代理类的获取

    在文章:Mybatis源码解析,一步一步从浅入深(二):按步骤解析源码中我们提到了两个问题: 1,为什么在以前的代码流程中从来没有addMapper,而这里却有getMapper? 2,UserDao ...

  3. mybatis源码-解析配置文件(三)之配置文件Configuration解析

    目录 1. 简介 1.1 系列内容 1.2 适合对象 1.3 本文内容 2. 配置文件 2.1 mysql.properties 2.2 mybatis-config.xml 3. Configura ...

  4. Mybatis源码解析(一) —— mybatis与Spring是如何整合的?

    Mybatis源码解析(一) -- mybatis与Spring是如何整合的?   从大学开始接触mybatis到现在差不多快3年了吧,最近寻思着使用3年了,我却还不清楚其内部实现细节,比如: 它是如 ...

  5. Mybatis源码解析(四) —— SqlSession是如何实现数据库操作的?

    Mybatis源码解析(四) -- SqlSession是如何实现数据库操作的?   如果拿一次数据库请求操作做比喻,那么前面3篇文章就是在做请求准备,真正执行操作的是本篇文章要讲述的内容.正如标题一 ...

  6. Mybatis源码解析,一步一步从浅入深(一):创建准备工程

    Spring SpringMVC Mybatis(简称ssm)是一个很流行的java web框架,而Mybatis作为ORM 持久层框架,因其灵活简单,深受青睐.而且现在的招聘职位中都要求应试者熟悉M ...

  7. Mybatis源码解析,一步一步从浅入深(二):按步骤解析源码

    在文章:Mybatis源码解析,一步一步从浅入深(一):创建准备工程,中我们为了解析mybatis源码创建了一个mybatis的简单工程(源码已上传github,链接在文章末尾),并实现了一个查询功能 ...

  8. Mybatis源码解析,一步一步从浅入深(四):将configuration.xml的解析到Configuration对象实例

    在Mybatis源码解析,一步一步从浅入深(二):按步骤解析源码中我们看到了XMLConfigBuilder(xml配置解析器)的实例化.而且这个实例化过程在文章:Mybatis源码解析,一步一步从浅 ...

  9. Mybatis源码解析(二) —— 加载 Configuration

    Mybatis源码解析(二) -- 加载 Configuration    正如上文所看到的 Configuration 对象保存了所有Mybatis的配置信息,也就是说mybatis-config. ...

随机推荐

  1. FormData提交文件(十四)

    问题 在通过ajax提交表单时,表单中有Excel文件,在后台还需要读取excel文件中的数据,普通的提交方式无法实现.可以通过创建FormData对象的方式. 代码示例: 前端: 创建想要提交的fo ...

  2. 图像旋转的FPGA实现(一)

    继续图像处理专题,这次写的是图像旋转.若要说小分辨率的图像旋转倒也简单,直接将原始图像存储在BRAM中,然后按照旋转后的位置关系取出便是.但是对于高分辨的图像(720P及以上)就必须得用DDR3或者D ...

  3. jvm源码解读--18 Java的start()方法解读 以及 wait 和notify流程图

    drawwed by 张艳涛 and get info from openjdk8 还有一个图

  4. Django < 2.0.8 任意URL跳转漏洞(CVE-2018-14574)

    影响版本 Django < 2.0.8 抓包 访问http://192.168.49.2:8000//www.example.com,即可返回是301跳转到//www.example.com

  5. DC-7靶机

    仅供个人娱乐 靶机信息 下载地址:http://www.five86.com/downloads/DC-7.zip 一.主机扫描 二.信息收集 或者 python3 cmseek.py --url h ...

  6. django有什么CMS比较好用?哪个好?

    这个网站有目前在电子商务领域流行的django cms的横向对比表格,可以看看 https://djangopackages.org/grids/g/ecommerce/ 从结果上来看,django- ...

  7. IPSec组播概要

    IPSec作为主流IP安全协议之一,在单播环境下,特别是在VPN场景中应用广泛.但是在组播环境貌似看到的不多,通过RFC4301了解到IPSec首先是支持组播的,即通过手动配置的方式可以实现组播包加密 ...

  8. 终于有人把Android技术面试知识体系整理出来了,这些学习手册让你的面试稳如泰山

    前言 年年寒冬,年年也挡不住一个安卓程序员追求大厂的决心.想要进入大厂,我们需要掌握哪些知识点呢?这里,我为大家梳理了一个整体的知识架构.整体包括Java.Android.算法.计算机基础等等,相应的 ...

  9. Linux线程属性总结(一)

    线程属性标识符:pthread_attr_t 包含在 pthread.h 头文件中. [c] view plaincopy //线程属性结构如下: typedef struct { int       ...

  10. 基于ivy的源代码调试方法

    项目PORJ_TEST是项目PROJ的测试项目.在它的ivy中引用了PROJ的jar包.由于PROJ正处于开发阶段,源代码更改频繁, 在运行PROJ_TEST中的测试时,需要进入PROJ的jar包内部 ...