1. 程式人生 > >Mybatis配置檔案(mybatis-config.xml )原始碼分析

Mybatis配置檔案(mybatis-config.xml )原始碼分析

Mybatis配置檔案(mybatis-config.xml )是我們在使用Mybatis的過程中必須掌握的基礎配置檔案,這個配置檔案中我們經常會配置如下標籤。

settings

<settings>
    <!-- 這個配置使全域性的對映器啟用或禁用快取 -->
    <setting name="cacheEnabled" value="false"/>
    <!-- 全域性啟用或禁用延遲載入。當禁用時,所有關聯物件都會即時載入 -->
     <setting name="lazyLoadingEnabled" value="true"/>
    <!-- 當啟用時,有延遲載入屬性的物件在被呼叫時將會完全載入任意屬性。否則,每種屬性將會按需要載入 -->
     <setting name="aggressiveLazyLoading" value="true"/>
    <!-- 允許或不允許多種結果集從一個單獨的語句中返回(需要適合的驅動) -->
     <setting name="multipleResultSetsEnabled" value="true"/>
    <!-- 使用列標籤代替列名。不同的驅動在這方便表現不同。參考驅動文件或充分測試兩種方法來決定所使用的驅動 -->
     <setting name="useColumnLabel" value="true"/>
    <!-- 允許JDBC支援生成的鍵。需要適合的驅動。如果設定為true則這個設定強制生成的鍵被使用,儘管一些驅動拒絕相容但仍然有效(比如Derby) -->
     <setting name="useGeneratedKeys" value="true"/>
    <!-- 指定MyBatis如何自動對映列到欄位/屬性。PARTIAL只會自動對映簡單,沒有巢狀的結果。FULL會自動對映任意複雜的結果(巢狀的或其他情況) -->
     <setting name="autoMappingBehavior" value="PARTIAL"/>
    <!-- 配置預設的執行器。SIMPLE執行器沒有什麼特別之處。REUSE執行器重用預處理語句。BATCH執行器重用語句和批量更新 -->
    <setting name="defaultExecutorType" value="REUSE"/>
    <!-- 設定超時時間,它決定驅動等待一個數據庫響應的時間 -->
    <setting name="defaultStatementTimeout" value="600"/>
</settings>

settings 標籤的Java解析過程
settings標籤的Java解析過程,我們可以檢視mybatis的原始碼:XMLConfigBuilder#parseConfiguration方法,上面已經對settings標籤的屬性做了註釋,我們在通過原始碼的分析會進一步瞭解這些屬性的作用。

private void parseConfiguration(XNode root) {
    try {
        Properties settings = settingsAsPropertiess(root.evalNode("settings"));
        //issue #117 read properties first
        propertiesElement(root.evalNode("properties"));
        loadCustomVfs(settings);
        typeAliasesElement(root.evalNode("typeAliases"));
        pluginElement(root.evalNode("plugins"));
        objectFactoryElement(root.evalNode("objectFactory"));
        objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
        reflectionFactoryElement(root.evalNode("reflectionFactory"));
        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-config.xml 中的settings標籤,同時也解析了這個配置檔案中包含的其他的標籤,以上方法是Mybatis解析配置檔案的核心處理方法,對於每一個標籤的作用我們後面再原始碼分析的過程中逐漸進行介紹。

setting各個屬性的預設值
重點可以關注:XMLConfigBuilder#settingsElement(settings) 方法的實現,我們就能明白在settings裡面的每個屬性的預設值是什麼了。

private void settingsElement(Properties props) throws Exception {
    configuration.setAutoMappingBehavior(AutoMappingBehavior.valueOf(props.getProperty("autoMappingBehavior", "PARTIAL")));
    configuration.setCacheEnabled(booleanValueOf(props.getProperty("cacheEnabled"), true));
    configuration.setProxyFactory((ProxyFactory) createInstance(props.getProperty("proxyFactory")));
    configuration.setLazyLoadingEnabled(booleanValueOf(props.getProperty("lazyLoadingEnabled"), false));
    configuration.setAggressiveLazyLoading(booleanValueOf(props.getProperty("aggressiveLazyLoading"), true));
    configuration.setMultipleResultSetsEnabled(booleanValueOf(props.getProperty("multipleResultSetsEnabled"), true));
    configuration.setUseColumnLabel(booleanValueOf(props.getProperty("useColumnLabel"), true));
    configuration.setUseGeneratedKeys(booleanValueOf(props.getProperty("useGeneratedKeys"), false));
    configuration.setDefaultExecutorType(ExecutorType.valueOf(props.getProperty("defaultExecutorType", "SIMPLE")));
    configuration.setDefaultStatementTimeout(integerValueOf(props.getProperty("defaultStatementTimeout"), null));
    configuration.setDefaultFetchSize(integerValueOf(props.getProperty("defaultFetchSize"), null));
    configuration.setMapUnderscoreToCamelCase(booleanValueOf(props.getProperty("mapUnderscoreToCamelCase"), false));
    configuration.setSafeRowBoundsEnabled(booleanValueOf(props.getProperty("safeRowBoundsEnabled"), false));
    configuration.setLocalCacheScope(LocalCacheScope.valueOf(props.getProperty("localCacheScope", "SESSION")));
    configuration.setJdbcTypeForNull(JdbcType.valueOf(props.getProperty("jdbcTypeForNull", "OTHER")));
    configuration.setLazyLoadTriggerMethods(stringSetValueOf(props.getProperty("lazyLoadTriggerMethods"), "equals,clone,hashCode,toString"));
    configuration.setSafeResultHandlerEnabled(booleanValueOf(props.getProperty("safeResultHandlerEnabled"), true));
    configuration.setDefaultScriptingLanguage(resolveClass(props.getProperty("defaultScriptingLanguage")));
    configuration.setCallSettersOnNulls(booleanValueOf(props.getProperty("callSettersOnNulls"), false));
    configuration.setLogPrefix(props.getProperty("logPrefix"));
    configuration.setLogImpl(resolveClass(props.getProperty("logImpl")));
    configuration.setConfigurationFactory(resolveClass(props.getProperty("configurationFactory")));
}