2.Configuration

一個典型的配置

<?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有一套語法,  當然現(xiàn)在用的是最簡單的. 就是查找所有的mappers/typeHandlers... 節(jié)點而已

最重要的 mapper parse 過程:



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

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

由于ResultMap支持extends,支持ER關聯(lián)


 
<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已經(jīng)包含了構造器, 最終映像里的繼承的resultMap里面的構造器會剔除掉.
resultMap已經(jīng)包含的映射, 同時在繼承的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, 可以看到我們經(jīng)常見到的property,column,jdbcType,javaType, 以及部分用的不太多的關聯(lián)查詢字段.

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;
//是否延遲加載, 對應節(jié)點的 fetchType 屬性
  private boolean lazy;
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容