mybatis解析settings标签

发布时间 2023-12-07 22:29:33作者: 神行诸葛

settings标签也是一个很重要的标签,虽然我们在使用的时候,没怎么配置settings标签里面的内容。好像一开始为了看sql语句,我们在settings标签里面配置了日志。

<settings>
        <setting name="logImpl" value="SLF4J"/>
    </settings>

其他的好像就没干什么了。其实settings标签里面的配置,还是跟mybatis的全局对象Configuration有关。直接看下解析这个标签的代码

XMLConfigBuilder:
private Properties settingsAsProperties(XNode context) {
    if (context == null) {
      return new Properties();
    }
    //将settings标签里面的子标签解析出来,并且放到一个Properties对象中
    Properties props = context.getChildrenAsProperties();
    // Check that all settings are known to the configuration class
    //localReflectorFactory->DefaultReflectorFactory
    MetaClass metaConfig = MetaClass.forClass(Configuration.class, localReflectorFactory);
    //这个for循环就是在判断settings标签内部的元素是不是在Configuration对象中,就看Configuration是否有set方法
    for (Object key : props.keySet()) {
      //如果settings标签里面配置的key在Configuration中找不到对应的方法,那么报错
      if (!metaConfig.hasSetter(String.valueOf(key))) {
        throw new BuilderException("The setting " + key + " is not known.  Make sure you spelled it correctly (case sensitive).");
      }
    }
    return props;
  }

这段代码也不难,就是将settings里面配置的标签转化为Prop对象。然后循环遍历key,如果key作为Configuration对象里面成员变量,如果这个成员变量没有对应的set方法,则报错。所以这里我们推断,settings里面配置的key和value,最终通过Configuration里面的set方法设置给对应的成员变量。比如上面我们配置的日志,就设置给了Configuration里面的日志对象。

Configuration里面的成员变量非常多,对应的set方法也非常多,所以settings里面的配置也非常多。那么接下来我们继续看看他把settings标签解析完后,获取Prop对象,又干了什么,看这个方法。

XMLConfigBuilder#  
private void settingsElement(Properties props) {
//configuration就是全局配置对象,看看有这么多成员变量需要set的,如果你没有在settings里面配,还给了默认值。
    configuration.setAutoMappingBehavior(AutoMappingBehavior.valueOf(props.getProperty("autoMappingBehavior", "PARTIAL")));
    configuration.setAutoMappingUnknownColumnBehavior(AutoMappingUnknownColumnBehavior.valueOf(props.getProperty("autoMappingUnknownColumnBehavior", "NONE")));
    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"), false));
    configuration.setMultipleResultSetsEnabled(booleanValueOf(props.getProperty("multipleResultSetsEnabled"), true));
    configuration.setUseColumnLabel(booleanValueOf(props.getProperty("useColumnLabel"), true));
    configuration.setUseGeneratedKeys(booleanValueOf(props.getProperty("useGeneratedKeys"), false));
    //设置mybatis默认的执行器,不配就是 SIMPLE
    configuration.setDefaultExecutorType(ExecutorType.valueOf(props.getProperty("defaultExecutorType", "SIMPLE")));
    configuration.setDefaultStatementTimeout(integerValueOf(props.getProperty("defaultStatementTimeout"), null));
    configuration.setDefaultFetchSize(integerValueOf(props.getProperty("defaultFetchSize"), null));
    configuration.setDefaultResultSetType(resolveResultSetType(props.getProperty("defaultResultSetType")));
    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.setDefaultEnumTypeHandler(resolveClass(props.getProperty("defaultEnumTypeHandler")));
    configuration.setCallSettersOnNulls(booleanValueOf(props.getProperty("callSettersOnNulls"), false));
    configuration.setUseActualParamName(booleanValueOf(props.getProperty("useActualParamName"), true));
    configuration.setReturnInstanceForEmptyRow(booleanValueOf(props.getProperty("returnInstanceForEmptyRow"), false));
    configuration.setLogPrefix(props.getProperty("logPrefix"));
    configuration.setConfigurationFactory(resolveClass(props.getProperty("configurationFactory")));
    configuration.setShrinkWhitespacesInSql(booleanValueOf(props.getProperty("shrinkWhitespacesInSql"), false));
    configuration.setDefaultSqlProviderType(resolveClass(props.getProperty("defaultSqlProviderType")));
  }

是不是挺吓人的。。。。至于Configuration里面那么多对象干嘛的,这是后面要研究的事情,而且这么多,我们肯定得挑几个重点的看看。

好的,本节告一段落。