运维开发网

MyBatis 源码解析 —— SqlSessionFactory

运维开发网 https://www.qedev.com 2020-03-09 18:02 出处:51CTO 作者:Java_老男孩
本文主要分析SqlSessionFactory的构建过程SqlSessionFactoryBuilder从XML中构建SqlSessionFactoryStringresource="org/mybatis/example/mybatis-config.xml";InputStreaminputStream=Resources.getResourceAsStream(resource);SqlSe

本文主要分析SqlSessionFactory的构建过程

SqlSessionFactoryBuilder从XML中构建SqlSessionFactory

String resource = "org/mybatis/example/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

MyBatis 源码解析 —— SqlSessionFactory

SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

SqlSessionFactoryBuilder用来创建SqlSessionFactory实例,一旦创建了SqlSessionFactory,就不再需要它了

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

调用

public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties)

源码如下:

/**
   * 根据配置创建SqlSessionFactory
   *
   * @param inputStream 配置文件输入流
   * @param environment 环境名称
   * @param properties  外部配置
   * @return
   */
  public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
    try {
      XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
      //parser.parse()读取配置文件返回configuration
      //build()根据返回的configuration创建SqlSessionFactory
      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.
      }
    }
  }

最终创建DefaultSqlSessionFactory实例

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

其中

XMLConfigBuilder与Configuration

MyBatis 源码解析 —— SqlSessionFactory

XMLConfigBuilder的方法parse()

public Configuration parse() {
    if (parsed) {
        throw new BuilderException("Each XMLConfigBuilder can only be used once.");
    }
    parsed = true;
    //读取mybatis-config.xml配置信息,"configuration"是根结点
    parseConfiguration(parser.evalNode("/configuration"));
    return configuration;
}

XMLConfigBuilder的方法parseConfiguration(XNode root)

/**
 * 读取配置文件组装configuration
 * @param root 配置文件的configuration节点
 */
private void parseConfiguration(XNode root) {
    try {
        //issue #117 read properties first
        propertiesElement(root.evalNode("properties"));
        typeAliasesElement(root.evalNode("typeAliases"));
        pluginElement(root.evalNode("plugins"));
        objectFactoryElement(root.evalNode("objectFactory"));
        objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
        reflectionFactoryElement(root.evalNode("reflectionFactory"));
        settingsElement(root.evalNode("settings"));
        // read it after objectFactory and objectWrapperFactory issue #631
        environmentsElement(root.evalNode("environments"));
        databaseIdProviderElement(root.evalNode("databaseIdProvider"));
        typeHandlerElement(root.evalNode("typeHandlers"));
        mapperElement(root.evalNode("mappers"));
    } catch (Exception e) {
        throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
    }
}

关于配置文件相关的源码分析参看:

http://www.iocoder.cn/MyBatis/udbwcso/Configuration

设计模式

从SqlSessionFactory和Configuration的创建过程中可以看出它们都使用了建造者模式.

0

精彩评论

暂无评论...
验证码 换一张
取 消