美文网首页
2.Configuration

2.Configuration

作者: 元隐 | 来源:发表于2020-01-15 18:28 被阅读0次

一个典型的配置

<?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>
    <properties resource="db.properties"></properties>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"></property>
                <property name="url" value="${jdbc.url}"></property>
                <property name="username" value="${jdbc.username}"></property>
                <property name="password" value="${jdbc.password}"></property>
            </dataSource>
        </environment>
    </environments>
    
</configuration>

<configuration>
<properties resource="properties/db.properties"/>
<settings>
<setting name="cacheEnabled" value="true"/>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="useGeneratedKeys" value="true"/>
</settings>
<typeAliases>
<typeAlias alias="AdminMap" type="pojo.AdminMap"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driveClass}"/>
<property name="url" value="${url}"/>
<property name="username" value="${userName}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<!--加载映射文件-->
    <mappers>
        <mapper resource="mapper/adminMap.xml"></mapper>
        <mapper resource="mapper/mapper.xml"></mapper>
    </mappers>
</configuration>

典型的XMLConfigBuilder

private void parseConfiguration(XNode root) {
    try {
      //issue #117 read properties first
      propertiesElement(root.evalNode("properties"));
      Properties settings = settingsAsProperties(root.evalNode("settings"));
      loadCustomVfs(settings);
      loadCustomLogImpl(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);
    }
  }

evalNode最终使用的是xpath的evalNode. xpath有一套语法,  当然现在用的是最简单的. 就是查找所有的mappers/typeHandlers... 节点而已

最重要的 mapper parse 过程:



 public void parse() {
    if (!configuration.isResourceLoaded(resource)) {
      configurationElement(parser.evalNode("/mapper"));
      configuration.addLoadedResource(resource);
      bindMapperForNamespace();
    }

    parsePendingResultMaps();
    parsePendingCacheRefs();
    parsePendingStatements();
  }

由于ResultMap支持extends,支持ER关联


 
<resultMap type= "Blog" id="blogResultMap" autoMapping ="true">
         <id property="id" column="id" /> 
         <result property="authorid" column="authorid" />
         <!-- manyToOne -->
         <association property ="author" column="authorid" javaType= "Author">
             <id property ="id" column="bid" />
             <!-- 或者使用 <id property ="id" column="authorid" />  -->
             <result property ="name" column="bname" />
             <result property ="age" column="age" />
         </association>
     </resultMap>

可以看到, 解析resultMap的过程,对于无extend的, 直接build即可, 对于有extend的则需要将extends的resultMap也加入resultMap列表.
同时有几个特殊的处理, resultMap已经包含了构造器, 最终映像里的继承的resultMap里面的构造器会剔除掉.
resultMap已经包含的映射, 同时在继承的resultMap也存在的, 也做了去重工作.

public ResultMap addResultMap(
      String id,
      Class<?> type,
      String extend,
      Discriminator discriminator,
      List<ResultMapping> resultMappings,
      Boolean autoMapping) {
    id = applyCurrentNamespace(id, false);
    extend = applyCurrentNamespace(extend, true);

    if (extend != null) {
      if (!configuration.hasResultMap(extend)) {
        throw new IncompleteElementException("Could not find a parent resultmap with id '" + extend + "'");
      }
      ResultMap resultMap = configuration.getResultMap(extend);
      List<ResultMapping> extendedResultMappings = new ArrayList<>(resultMap.getResultMappings());
      extendedResultMappings.removeAll(resultMappings);
      // Remove parent constructor if this resultMap declares a constructor.
      boolean declaresConstructor = false;
      for (ResultMapping resultMapping : resultMappings) {
        if (resultMapping.getFlags().contains(ResultFlag.CONSTRUCTOR)) {
          declaresConstructor = true;
          break;
        }
      }
      if (declaresConstructor) {
        extendedResultMappings.removeIf(resultMapping -> resultMapping.getFlags().contains(ResultFlag.CONSTRUCTOR));
      }
      resultMappings.addAll(extendedResultMappings);
    }
    ResultMap resultMap = new ResultMap.Builder(configuration, id, type, resultMappings, autoMapping)
        .discriminator(discriminator)
        .build();
    configuration.addResultMap(resultMap);
    return resultMap;
  }

以下是一个resultMapping, 可以看到我们经常见到的property,column,jdbcType,javaType, 以及部分用的不太多的关联查询字段.

public class ResultMapping {

  private Configuration configuration;
  private String property;
  private String column;
  private Class<?> javaType;
  private JdbcType jdbcType;
// 类型转换handler
  private TypeHandler<?> typeHandler;
  private String nestedResultMapId;
  private String nestedQueryId;
// 对应于配置 ex:notNullColumn="id"
  private Set<String> notNullColumns;
  private String columnPrefix; 
//处理后的标记, 有两种:id和constructor, 也就是properties注入的两个办法, setter and 构造
  private List<ResultFlag> flags;
  private List<ResultMapping> composites;
  private String resultSet;
  private String foreignColumn;
//是否延迟加载, 对应节点的 fetchType 属性
  private boolean lazy;

相关文章

网友评论

      本文标题:2.Configuration

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