MyBatis学习笔记_day01解析全局配置文件

解析全局配置文件

悟已往之不谏知来者之可追。

1. 解析全局配置文件

1.1 启动流程分析

String resource = "mybatis-config.xml";
//将XML配置文件构建为Configuration配置类
reader = Resources.getResourceAsReader(resource);
// 通过加载配置文件流构建一个SqlSessionFactory DefaultSqlSessionFactory
SqlSessionFactory sqlMapper = new SqlSessionFactoryBuilder().build(reader);

通过上面代码发现,创建SqlSessionFactory 的代码在SqlSessionFactoryBuilder

//整个过程就是将配置文件解析成Configration对象,然后创建SqlSessionFactory的过程
//Configuration是SqlSessionFactory的一个内部属性
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.
      }
    }
  }
    
  public SqlSessionFactory build(Configuration config) {
   
    return new DefaultSqlSessionFactory(config);
  }

看下解析配置文件过程中的细节。

<mark>配置文件</mark>

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
  <!--SqlSessionFactoryBuilder中配置的配置文件的优先级最高;config.properties配置文件的优先级次之;properties标签中的配置优先级最低 -->
  <properties resource="org/mybatis/example/config.properties">
    <property name="username" value="dev_user"/>
    <property name="password" value="F2Fa3!33TYyg"/>
  </properties>

  <!--一些重要的全局配置-->
  <settings>
  <setting name="cacheEnabled" value="true"/>
  <!--<setting name="lazyLoadingEnabled" value="true"/>-->
  <!--<setting name="multipleResultSetsEnabled" value="true"/>-->
  <!--<setting name="useColumnLabel" value="true"/>-->
  <!--<setting name="useGeneratedKeys" value="false"/>-->
  <!--<setting name="autoMappingBehavior" value="PARTIAL"/>-->
  <!--<setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>-->
  <!--<setting name="defaultExecutorType" value="SIMPLE"/>-->
  <!--<setting name="defaultStatementTimeout" value="25"/>-->
  <!--<setting name="defaultFetchSize" value="100"/>-->
  <!--<setting name="safeRowBoundsEnabled" value="false"/>-->
  <!--<setting name="mapUnderscoreToCamelCase" value="false"/>-->
  <!--<setting name="localCacheScope" value="STATEMENT"/>-->
  <!--<setting name="jdbcTypeForNull" value="OTHER"/>-->
  <!--<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>-->
  <!--<setting name="logImpl" value="STDOUT_LOGGING" />-->
  </settings>

  <typeAliases>

  </typeAliases>

  <plugins>
      <plugin interceptor="com.github.pagehelper.PageInterceptor">
          <!--默认值为 false,当该参数设置为 true 时,如果 pageSize=0 或者 RowBounds.limit = 0 就会查询出全部的结果-->
          <!--如果某些查询数据量非常大,不应该允许查出所有数据-->
          <property name="pageSizeZero" value="true"/>
      </plugin>
  </plugins>

  <environments default="development">
      <environment id="development">
          <transactionManager type="JDBC"/>
          <dataSource type="POOLED">
              <property name="driver" value="com.mysql.jdbc.Driver"/>
              <property name="url" value="jdbc:mysql://10.59.97.10:3308/windty"/>
              <property name="username" value="windty_opr"/>
              <property name="password" value="windty!234"/>
          </dataSource>
      </environment>
  </environments>

  <databaseIdProvider type="DB_VENDOR">
      <property name="MySQL" value="mysql" />
      <property name="Oracle" value="oracle" />
  </databaseIdProvider>

  <mappers>
      <!--这边可以使用package和resource两种方式加载mapper-->
      <!--<package name="包名"/>-->
      <!--<mapper resource="./mappers/SysUserMapper.xml"/>-->
      <mapper resource="./mappers/CbondissuerMapper.xml"/>
  </mappers>

</configuration>

解析配置文件的核心方法

private void parseConfiguration(XNode root) {
   
    try {
   
      //issue #117 read properties first
      //解析properties标签,并set到Configration对象中
      //在properties配置属性后,在Mybatis的配置文件中就可以使用${key}的形式使用了。
      propertiesElement(root.evalNode("properties"));
      
      //解析setting标签的配置
      Properties settings = settingsAsProperties(root.evalNode("settings"));
      //添加vfs的自定义实现,这个功能不怎么用
      loadCustomVfs(settings);
        
      //配置类的别名,配置后就可以用别名来替代全限定名
      //mybatis默认设置了很多别名,参考附录部分
      typeAliasesElement(root.evalNode("typeAliases"));
        
      //解析拦截器和拦截器的属性,set到Configration的interceptorChain中
      //MyBatis 允许你在已映射语句执行过程中的某一点进行拦截调用。默认情况下,MyBatis 允许使用插件来拦截的方法调用包括:
      //Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
        //ParameterHandler (getParameterObject, setParameters)
        //ResultSetHandler (handleResultSets, handleOutputParameters)
        //StatementHandler (prepare, parameterize, batch, update, query)
      pluginElement(root.evalNode("plugins"));
      
      //Mybatis创建对象是会使用objectFactory来创建对象,一般情况下不会自己配置这个objectFactory,使用系统默认的objectFactory就好了
      objectFactoryElement(root.evalNode("objectFactory"));
      objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
      reflectorFactoryElement(root.evalNode("reflectorFactory"));
       
      //设置在setting标签中配置的配置
      settingsElement(settings);
   
      //解析环境信息,包括事物管理器和数据源,SqlSessionFactoryBuilder在解析时需要指定环境id,如果不指定的话,会选择默认的环境;
      //最后将这些信息set到Configration的Environment属性里面
      environmentsElement(root.evalNode("environments"));
        
      //
      databaseIdProviderElement(root.evalNode("databaseIdProvider"));
        
      //无论是 MyBatis 在预处理语句(PreparedStatement)中设置一个参数时,还是从结果集中取出一个值时, 都会用类型处理器将获取的值以合适的方式转换成 Java 类型。解析typeHandler。
      typeHandlerElement(root.evalNode("typeHandlers"));
      //解析Mapper
      mapperElement(root.evalNode("mappers"));
    } catch (Exception e) {
   
      throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
    }
}


解析流程结束后会生成一个Configuration对象,包含所有配置信息,然后会创建一个 SqlSessionFactory 对象,这个对象包含了Configuration对象。

<mark>简单总结:</mark>

对于 MyBatis 启动流程:

  • SqlSessionFactoryBuilder 解析配置文件,包括属性配置、别名配置、拦截器配置、环境(数据源和事务管理器)、Mapper 配置等;

  • 解析完这些配置后会生成一个Configuration 对象,这个对象中包含了 MyBatis 需要的所有配置

  • 用这个 Configuration 对象创建一个SqlSessionFactory对象,这个对象中包含了 Configuration 对象。

全部评论

相关推荐

只因飞飞:今日首绷
点赞 评论 收藏
分享
迷茫的大四🐶:那你问他上班之后老实了没
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务