美文网首页
Mybatis构建SqlSessionFactory(2)201

Mybatis构建SqlSessionFactory(2)201

作者: Seetheworl_6675 | 来源:发表于2018-08-19 21:12 被阅读0次

     今天我们来根据上一篇Mybatis(1)的案例我们来追追下源码:
    我们从mybatis主要构件的执行流程:

    mybatis.png
    那么我们先来看看SqlSessionFactoryBuilder创建SqlSessionFacctory的过程:
    这边我们SqlSessionFactoryBuilder这个类:
    public class SqlSessionFactoryBuilder {
        public SqlSessionFactoryBuilder() {
        }
      //Reader读取mybatis配置文件
        public SqlSessionFactory build(Reader reader) {
            return this.build((Reader)reader, (String)null, (Properties)null);
        }
         //Reader读取mybatis配置文件
        //Environment决定加载哪种环境(开发环境/生产环境)
        public SqlSessionFactory build(Reader reader, String environment) {
            return this.build((Reader)reader, environment, (Properties)null);
        }
         //mybatis配置文件 + properties, mybatis配置文件中能使用${}形式
        public SqlSessionFactory build(Reader reader, Properties properties) {
            return this.build((Reader)reader, (String)null, properties);
        }
        //通过XMLConfigBuilder解析mybatis配置,然后创建SqlSessionFactory对象
        public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
            SqlSessionFactory var5;
            try {
                XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
                var5 = this.build(parser.parse());
            } catch (Exception var14) {
                throw ExceptionFactory.wrapException("Error building SqlSession.", var14);
            } finally {
                ErrorContext.instance().reset();
    
                try {
                    reader.close();
                } catch (IOException var13) {
                    ;
                }
    
            }
    
            return var5;
        }
      //以下4个方法都只是Reader换成了InputStream
        public SqlSessionFactory build(InputStream inputStream) {
            return this.build((InputStream)inputStream, (String)null, (Properties)null);
        }
    
        public SqlSessionFactory build(InputStream inputStream, String environment) {
            return this.build((InputStream)inputStream, environment, (Properties)null);
        }
    
        public SqlSessionFactory build(InputStream inputStream, Properties properties) {
            return this.build((InputStream)inputStream, (String)null, properties);
        }
    
        public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
            SqlSessionFactory var5;
            try {
                XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
                var5 = this.build(parser.parse());
            } catch (Exception var14) {
                throw ExceptionFactory.wrapException("Error building SqlSession.", var14);
            } finally {
                ErrorContext.instance().reset();
    
                try {
                    inputStream.close();
                } catch (IOException var13) {
                    ;
                }
    
            }
    
            return var5;
        }
        //最后一个build方法使用了一个Configuration作为参数,并返回DefaultSqlSessionFactory
        public SqlSessionFactory build(Configuration config) {
            return new DefaultSqlSessionFactory(config);
        }
    }
    
    

     从SqlSessionFactoryBuilder的代码我们可以总结出创建SqlSessionFactory的方式实际上是有两种:

    1、不使用XML构建SqlSessionFactory :

    实际上就是我们上一个篇张中使用的案例。就是使用Java程序而不是XML文件中直接创建配置实例,然后通过高 public SqlSessionFactory build(Configuration config) ;去创建SqlSessionFactory实例;

    2、从XML中构建SqlSessionFactory :

    实际上就是我们平常开发中常用的通过XML文件中构建SqlSessionFactory的实例;

    不使用XML构建SqlSessionFactory,比较简单,我们这里主要看看从XML中构建SqlSessionFactory 的过程:
        //通过XMLConfigBuilder解析mybatis配置,然后创建SqlSessionFactory对象
        //参数reader:根据XML文档获取的Reader实例。
        //参数environment:决定加载哪种环境(开发环境/生产环境)
        //参数properties:那些properties(属性配置文件),那些属性可以用${propName}语法在配置文件中使用
        public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
            SqlSessionFactory var5;
            try {
                //委托XMLConfigBuilder来解析xml文件
                XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
                //构建SqlSessionFactory
                var5 = this.build(parser.parse());
            } catch (Exception var14) {
                throw ExceptionFactory.wrapException("Error building SqlSession.", var14);
            } finally {
                ErrorContext.instance().reset();
    
                try {
                    reader.close();
                } catch (IOException var13) {
                    ;
                }
    
            }
    
            return var5;
        }
    

    接着我们来看看:
    new XMLConfigBuilder(reader, environment, properties):

    public XMLConfigBuilder(Reader reader, String environment, Properties props) {
        this(new XPathParser(reader, true, props, new XMLMapperEntityResolver()), environment, props);
      }
    
    private XMLConfigBuilder(XPathParser parser, String environment, Properties props) {
        super(new Configuration());
        ErrorContext.instance().resource("SQL Mapper Configuration");
        this.configuration.setVariables(props);
        this.parsed = false;
        this.environment = environment;
        this.parser = parser;
      }
    

    从代码我们可以看出来XMLConfigBuilder构健过程初始化的组件有:
    Reader:通过xml配置文件获取的实例Reader
    Properties:properties的配置信息对应的实例Properties
    Evironment:环境对象
    XMLMapperEntityResolver:DTDs校验xml配置语法的对象
    XPathParser:xml的解析器。

    接着我们来看看:SqlSessionthis.build(parser.parse()) :
    先看下中:parser.parse():

    public Configuration parse() {
        if (parsed) {
          throw new BuilderException("Each XMLConfigBuilder can only be used once.");
        }
        parsed = true;
        //从根节点configuration
        parseConfiguration(parser.evalNode("/configuration"));
        return configuration;
      }
    
      private void parseConfiguration(XNode root) {
        try {
          //issue #117 read properties first
          propertiesElement(root.evalNode("properties"));
          Properties settings = settingsAsProperties(root.evalNode("settings"));
          loadCustomVfs(settings);
          typeAliasesElement(root.evalNode("typeAliases"));
          pluginElement(root.evalNode("plugins"));
          objectFactoryElement(root.evalNode("objectFactory"));
          objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
          reflectorFactoryElement(root.evalNode("reflectorFactory"));
          settingsElement(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);
        }
      }
    

    从上面的代码我们就能看出,在mybatis的配置文件中:configuration节点之下,可以配置的信息分别为:
    Properties全局参数
    TypeAliases别名
    Plugin插件
    ObjectFactory对象
    objectWrapperFactory
    Settings设置
    Environment环境
    DatabaseidProvider 数据库标识
    TypeHandler类型处理器
    Mapper映射器

    最后通过build(Configuration config)构建SqlSessionFactory:

    public SqlSessionFactory build(Configuration config) {
        return new DefaultSqlSessionFactory(config);
      }
    
    总结下:
    SqlSessionFactory构建过程(SqlSessionFactoryBuilder):
    第一步:通过XMLConfigBuilder解析XML文件,读取配置信息,并保存到Configuration类中。备注:Mybatis几乎所有的配置都是保存在Configuration
    第二部:使用Confinguration对象去创建SqlSessionFactory。备注:SqlSessionFactory是一个接口。
    
    构建Configuration构建过程:

    第一步:读取配置文件,包括基础配置的XML文件和映射器的XML文件
    第二步:初始化基础配置比如Mybatis的别名等,一些重要的类对象,(插件,映射器,ObjectFatory,typeHandler对象等)
    第三步:提供单例,为后续创建SessionFactory服务并提供配置参数
    第四步:执行一些重要的对象方法,初始化配置信息。

    初始化:
    Properties全局参数
    Settings设置
    TypeAliases别名
    TypeHandler类型处理器
    ObjectFactory对象
    Plugin插件
    Environment环境
    DatabaseidProvider 数据库标识
    Mapper映射器

    相关文章

      网友评论

          本文标题:Mybatis构建SqlSessionFactory(2)201

          本文链接:https://www.haomeiwen.com/subject/xgjabftx.html