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配置信息的读取和解析就完成了