mybatis源码学习(五)

mybatis加载settings

上一篇讲完了mybatis加载properties配置,在启动的时候,会根据配置文件加载properties信息,在加载的时候,会有三种不同的顺序。当mybatis加载完properties了之后,接在会加载settings信息。mybatis的settings配置是最复杂的。它能深刻影响 MyBatis 底层的运行,但是在大部分情况下使用默认值便可以运行,所以在大部分情况下不需要大量配置它,只需要修改一些常用的规则即可,比如自动映射、驼峰命名映射、级联规则、是否启动缓存、执行器(Executor)类型等。
setting的配置文件如下:

    <settings>
        <!--是否开启全局缓存,默认true-->
        <setting name="cacheEnabled" value="true"/>
        <!--是否开启延迟加载,当开启时,所关联对象都会延迟加载,在特定关联关系中,可通过设置fetchType属性来覆盖该项,默认false-->
        <setting name="lazyLoadingEnabled" value="true"/>
        <!--是否允许单一语句返回多结果集,默认true-->
        <setting name="multipleResultSetsEnabled" value="true"/>
        <!--对任意延迟属性的调用会使带有延迟加载属性的对象完整加载,不开启的时候,每种属性将会按需加载,默认false-->
        <setting name="aggressiveLazyLoading" value="true"/>
        <!--使用列标签代替列名,默认true-->
        <setting name="useColumnLabel" value="true"/>
        <!--允许jdbc支持自动生成主键,默认false-->
        <setting name="useGeneratedKeys" value="false"/>
        <!--指定自动映射到字段的规则,none取消自动映射,partial只映射没有定义嵌套结果集映射的结果集,full自动映射任何结果集,默认partial-->
        <setting name="autoMappingBehavior" value="PARTIAL"/>
        <!--指定当自动映射碰到未知列的处理规则,none不做任何处理,warning输入警告日志,failing抛出sqlsessionexception异常,默认none-->
        <setting name="autoMappingUnknownColumnBehavior" value="NONE"/>
        <!--配置默认执行器,simple普通执行器,reuse重用预处理语句,batch重用语句并执行批量更新,默认simple-->
        <setting name="defaultExecutorType" value="SIMPLE"/>
        <!--设置驱动等待数据库响应的超时时间-->
        <setting name="defaultStatementTimeout" value="25"/>
        <!--为驱动的结果集数量设置提示值-->
        <setting name="defaultFetchSize" value="25"/>
        <!--允许在嵌套语句中使用分页Rowounds,默认false-->
        <setting name="safeRowBoundsEnabled" value="false"/>
        <!--允许在嵌套语句中使用分页resulthandler,默认true-->
        <setting name="safeResultHandlerEnabled" value="true"/>
        <!--是否开启自动驼峰命名规则,默认false-->
        <setting name="mapUnderscoreToCamelCase" value="false"/>
        <!--利用本地缓存机制防止循环引用和加速重复嵌套查询,session缓存一个会话中执行的所有查询,statement本地会员只用在语句执行中,对相同的sqlsession的不通调用不会共享数据,默认session-->
        <setting name="localCacheScope" value="SESSION"/>
        <!--当没有为参数提供特定的jdbc类型时,为空值指定jdbc类型,other为一般类型,null为空值,varchar为字符串,默认为other-->
        <setting name="jdbcTypeForNull" value="OTHER"/>
        <!--指定哪个对象的方法触发一次延迟加载-->
        <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
    </settings>

在XMLConfigBuilder中,通过执行

Properties settings = settingsAsProperties(root.evalNode("settings"));
loadCustomVfs(settings);
.
.
.
settingsElement(settings);

先看settingsAsProperties,这个方法是读取配置文件信息,并检查,settings的配置里面,写的属性是否与mybatis本身定义的属性一样,如果存在不一样的属性,那么会报错。

private Properties settingsAsProperties(XNode context) {
    if (context == null) {
      return new Properties();
    }
    //读取settings下的所有setting信息
    Properties props = context.getChildrenAsProperties();
    // Check that all settings are known to the configuration class
    //根据Configuration对象反射出MetaClass对象,用于判断写的settings属性是否都是mybatis定义好的属性
    MetaClass metaConfig = MetaClass.forClass(Configuration.class, localReflectorFactory);
    for (Object key : props.keySet()) {
      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;
  }

loadCustomVfs(settings);是用来加载vfs,VFS含义是虚拟文件系统;主要是通过程序能够方便读取本地文件系统、FTP文件系统等系统中的文件资源。Mybatis中提供了VFS这个配置,主要是通过该配置可以加载自定义的虚拟文件系统应用程序。

private void loadCustomVfs(Properties props) throws ClassNotFoundException {
    String value = props.getProperty("vfsImpl");
    if (value != null) {
      String[] clazzes = value.split(",");
      for (String clazz : clazzes) {
        if (!clazz.isEmpty()) {
          @SuppressWarnings("unchecked")
          Class<? extends VFS> vfsImpl = (Class<? extends VFS>)Resources.classForName(clazz);
          configuration.setVfsImpl(vfsImpl);
        }
      }
    }
  }

允许配置多个vfs的自定义实现类。最后通过调用settingsElement(settings);方法去把settings的配置文件更新到configuration里面。

private void settingsElement(Properties props) throws Exception {
    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));
    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")));
    @SuppressWarnings("unchecked")
    Class<? extends TypeHandler> typeHandler = (Class<? extends TypeHandler>)resolveClass(props.getProperty("defaultEnumTypeHandler"));
    configuration.setDefaultEnumTypeHandler(typeHandler);
    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"));
    @SuppressWarnings("unchecked")
    Class<? extends Log> logImpl = (Class<? extends Log>)resolveClass(props.getProperty("logImpl"));
    configuration.setLogImpl(logImpl);
    configuration.setConfigurationFactory(resolveClass(props.getProperty("configurationFactory")));
  }

到这里,关于settings配置信息的读取和解析就完成了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值