【Mybatis】Mybatis学习由浅入深(三)

前言

  上一文提到了Mybatis的工作流程,这里回顾一下,然后这里主要讲第一步,加载配置信息初始化。

在这里插入图片描述

Mybatis在启动的时候都干了什么?🤔

  还是用上次的这个实现代码示例来开展吧。

  第一步就是“获取配置文件”,但是我们启动仅仅就获取下配置文件吗?当然不是,我们肯定是要解析配置文件,并将解析到的数据存起来供后面使用吧,这个是在哪里完成的呢?又是存在哪里呢?别着急这些问题后面解答。

  继续看下一行,使用Buider对象创建了一个SqlSessionFactory工厂对象,然后用这个创建了SqlSession才最终做到了和数据库的查询。啊?为啥要用Builder来创建啊,我直接new 一个不香吗?后面说后面说别急

在这里插入图片描述

  很明显SqlSession是完成和数据库交互的主力,而这个SqlSession怎么来的呢,是由SqlSessionFactory这个工厂创建的,给大家贴一下,基本全是返回SqlSession的,最后一个这里不提。可以看到这个接口的实现类有两个,不过直接获取,通过一个Buider对象创建的 SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);

在这里插入图片描述

配置文件在哪完成解析存起来的?🤔

  • new SqlSessionFactoryBuilder().build(in);创建工厂对象的时候完成的
  • 工厂对象的作用就是创建SqlSession,它不需要重复创建是一个单例对象
  • 我们的配置文件不管是全局配置文件还是映射文件,也都只需要加载一次就可以了
  • 这个SqlSessionFactoryBuilder就是用建造者模式完成这两个步骤,加载配置文件和创建工厂对象

源码证实🔭:

SqlSessionFactoryBuilder源码📖
  public SqlSessionFactory build(InputStream inputStream) {
    return build(inputStream, null, null);
  } 

  public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
    try {
      // 用于解析 mybatis-config.xml
      XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
      // 解析XML,最终返回一个 DefaultSqlSessionFactory
      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.
      }
    }
  }

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

  通过SqlSessionFactoryBuilder源码我们可以看到👇

  • 通过XMLConfigBuilder加载 Resources.getResourceAsStream("mybatis-config.xml") 加载得到的字节流。
  • XMLConfigBuilder初始化完成之后调用了parse方法得到了Configuration对象
  • 最终创建了一个DefaultSqlSessionFactory工厂对象返回
XMLConfigBuilder源码📖

在这里插入图片描述

  通过XMLConfigBuilder源码我们可以看到👇

  • 生成了一个xml解析器。
  • 初始化了一个Configuration对象。
  • 设置对应的properites属性。
  • 初始化是否解析的标志。
  • 初始化环境标识

  这是new XMLConfigBuilder完成的内容,这也只是完成解析的前置操作啊,解析,我要的解析在哪呢?别急马上就来,new XMLConfigBuilder之后不是还调用了parse方法吗?

在这里插入图片描述

在这里插入图片描述

  在这个parse中

  • 判定是否初始化一次
  • 完成对properties、settings等的解析处理工作

问题小结🔚

  mybatis在使用SqlSessionFactoryBuilder创建工厂对象的时候,借助XmlConfigBuider完成了对配置文件的解析工作和创建工厂对象工作。


Mybatis加载的内容存在哪个Java对象中?🤔

  上面的源码其实可以看出来,我们不是通过XmlConfigBuilder调用parse返回Configuration对象吗,然后用这个对象创建了DefaultSqlSessionFactory对象。那肯定是存在Configuration对象里咯😊

源码证实

  上面的源码跟到parse下面的parseConfiguration方法,看到里面针对很多标签的操作,那么接着找
在这里插入图片描述

  可以看到,解析完成后的数据,最终都set进Configuration对象里了,说明我们的猜测是对的。


SqlSessionFactory为什么是用Builder创建的?🤔

  在这里其实用到了工厂模式、建造者模式。建造者模式啪啪啪一顿操作,就搞出来了一个工厂对象,我只要用对象就好,其实我不关心咋创建出来的。这说明了解除了我和工具的耦合,我只要用就好了,我不需要创建。你那些复杂的逻辑自己管理。

Statement体现在哪呢?🤔

  差点漏了,开头说了加载了Statement对象,这里说明一下,首先可以确认的是肯定存在了Configuration里面,那还是在XmlConfigBuilder里找

源码说明🔭

在这里插入图片描述

  解析mappers时候,可以看到最终都调用了XMLMapperBuilder的parse方法,

  • 在这个parse方法里调用了configurationElement方法
  • 然后在configurationElement里创建了XMLStatementBuilder,这个初始化XMLStatementBuilder创建了MapperBuilderAssistant对象
  • 然后在configurationElement里调用了XMLStatementBuilder的parseStatementNode方法
  • 在parseStatementNode里调用了MapperBuilderAssistant的addMappedStatement方法
  • 在addMappedStatement方法的最后可以看到,创建了MappedStatement对象放进Configuration对象里

总结🔚

  Mybatis在启动时候加载全局配置文件和映射文件并将数据存储在Configuration对象里,然后创建一个SqlSessionFactory工厂对象,下面画张图示意下SqlSessionFactory的创建。

请添加图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

泪梦殇雨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值