Mybaits源码分析四之XMLConfigBuilder类settings 标签解析
根据mybatis框架加载流程
1 private void parseConfiguration(XNode root) { 2 try { 3 //解析子节点的properties文件 4 propertiesElement(root.evalNode("properties")); 5 //加载用户自定义配置 6 Properties settings = settingsAsProperties(root.evalNode("settings")); 7 //加载vfs虚拟文件系统配置 8 loadCustomVfs(settings); 9 // 解析子节点typeAliases 别名 10 typeAliasesElement(root.evalNode("typeAliases")); 11 //解析子节点plugins 插件 12 pluginElement(root.evalNode("plugins")); 13 //解析子节点objectFactory mybatis为结果创建对象时都会用到objectFactory 14 objectFactoryElement(root.evalNode("objectFactory")); 15 //解析子节点的封装对象 16 objectWrapperFactoryElement(root.evalNode("objectWrapperFactory")); 17 reflectorFactoryElement(root.evalNode("reflectorFactory")); 18 //解析settings标签的文件配置 19 settingsElement(settings); 20 //配置运行环境 21 environmentsElement(root.evalNode("environments")); 22 //解析子节点配置数据库供应商 23 databaseIdProviderElement(root.evalNode("databaseIdProvider")); 24 //解析对象类型处理器,处理Java的pojo类型与数据库类型的映射 25 typeHandlerElement(root.evalNode("typeHandlers")); 26 //解析子节点的mappers 27 mapperElement(root.evalNode("mappers")); 28 } catch (Exception e) { 29 throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e); 30 } 31 }
<settings>标签配置为
1 <settings> 2 <!-- 该配置影响的所有映射器中配置的缓存的全局开关。默认值true --> 3 <setting name="cacheEnabled" value="true"/> 4 <!--延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置fetchType属性来覆盖该项的开关状态。默认值false --> 5 <setting name="lazyLoadingEnabled" value="true"/> 6 <!-- 是否允许单一语句返回多结果集(需要兼容驱动)。 默认值true --> 7 <setting name="multipleResultSetsEnabled" value="true"/> 8 <!-- 使用列标签代替列名。不同的驱动在这方面会有不同的表现, 具体可参考相关驱动文档或通过测试这两种不同的模式来观察所用驱动的结果。默认值true --> 9 <setting name="useColumnLabel" value="true"/> 10 <!-- 允许 JDBC 支持自动生成主键,需要驱动兼容。 如果设置为 true 则这个设置强制使用自动生成主键,尽管一些驱动不能兼容但仍可正常工作(比如 Derby)。 默认值false --> 11 <setting name="useGeneratedKeys" value="false"/> 12 <!-- 指定 MyBatis 应如何自动映射列到字段或属性。 NONE 表示取消自动映射;PARTIAL 只会自动映射没有定义嵌套结果集映射的结果集。 FULL 会自动映射任意复杂的结果集(无论是否嵌套)。 默认值PARTIAL --> 13 <setting name="autoMappingBehavior" value="PARTIAL"/> 14 <!--指定自动映射当中未知列(或未知属性类型)时的行为。 默认是不处理,只有当日志级别达到 WARN 级别或者以下,才会显示相关日志,如果处理失败会抛出 SqlSessionException 异常 默认NONE--> 15 <setting name="autoMappingUnknownColumnBehavior" value="WARNING"/> 16 <!-- 配置默认的执行器。SIMPLE 就是普通的执行器;REUSE 执行器会重用预处理语句(prepared statements); BATCH 执行器将重用语句并执行批量更新。默认SIMPLE --> 17 <setting name="defaultExecutorType" value="SIMPLE"/> 18 <!-- 设置超时时间,它决定驱动等待数据库响应的秒数。默认值null --> 19 <setting name="defaultStatementTimeout" value="25"/> 20 <!-- 设置数据库驱动程序默认返回的条数限制,此参数可以重新设置--> 21 <setting name="defaultFetchSize" value="100"/> 22 <!-- 允许在嵌套语句中使用分页(RowBounds)默认值False --> 23 <setting name="safeRowBoundsEnabled" value="false"/> 24 25 <!-- 是否开启自动驼峰命名规则(camel case)映射,即从经典数据库列名 A_COLUMN 到经典 Java 属性名 aColumn 的类似映射。 默认false --> 26 <setting name="mapUnderscoreToCamelCase" value="false"/> 27 <!-- MyBatis 利用本地缓存机制(Local Cache)防止循环引用(circular references)和加速重复嵌套查询。默认值为 SESSION,这种情况下会缓存一个会话中执行的所有查询。若设置值为 STATEMENT,本地会话仅用在语句执行上,对相同 SqlSession 的不同调用将不会共享数据。 --> 28 <setting name="localCacheScope" value="SESSION"/> 29 <!-- 当没有为参数提供特定的 JDBC 类型时,为空值指定 JDBC 类型。 某些驱动需要指定列的 JDBC 类型,多数情况直接用一般类型即可,比如 NULL、VARCHAR 或 OTHER。 --> 30 <setting name="jdbcTypeForNull" value="OTHER"/> 31 <!-- 指定哪个对象的方法触发一次延迟加载。 --> 32 <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/> 33 <!-- 允许在嵌套语句中使用分页(ResultHandler)。如果允许,设置false 默认值truet--> 34 <setting name="safeResultHandlerEnabled" value="false"/> 35 <!--当没有为参数提供特定的 JDBC 类型时,为空值指定 JDBC 类型。某些驱动需要指定列的 JDBC 类型,多数情况直接用一般类型即可,比如 NULL、VARCHAR 或 OTHER--> 36 <setting name="jdbcTypeForNull" value="OTHER"/> 37 <!--指定动态 SQL 生成的默认语言--> 38 <setting name="defaultScriptingLanguage" value="org.apache.ibatis.script.ing.xmltags.XMLDynamicLanguageDrive"/> 39 <!-- 指定当结果集中值为 null 时,是否调用映射对象的 setter(map 对象时为 put)方法,这对于 Map.kcySet() 依赖或 null 值初始化时是有用的。注意,基本类型(int、boolean 等)不能设置成 null--> 40 <setting name="callSettersOnNulls" value="false"/> 41 <!-- 指定 MyBatis 增加到日志名称的前缀 --> 42 <setting name="logPrefix" value="test_"/> 43 <!--指定 MyBatis 所用日志的具体实现,未指定时将自动査找--> 44 <setting name="loglmpl" value="LOG4J"/> 45 <!--指定 MyBatis 创建具有延迟加栽能力的对象所用到的代理工具--> 46 <setting name="proxyFactory" value="JAVASSIST"/> 47 <!-- 指定 VFS 的实现类, 提供 VFS 类的全限定名,如果存在多个,可以使用逗号分隔--> 48 <setting name="vfsImpl" value="com.ssc.demo.mybatis.dao.StudemtDaoImpl"/> 49 <!--允许用方法参数中声明的实际名称引用参数。要使用此功能,项目必须被编译为 Java 8 参数的选择。(从版本 3.4.1 开始可以使用) --> 50 <setting name="useActualParamName" value="true"/> 51 </settings>
调用 loadCustomVfs(settings);这行代码,是通过该配置可以加载自定义的虚拟文件
<setttings>便签写法为
1 <setting name="vfsImpl" value="com.ssc.demo.mybatis.dao.StudemtDaoImpl,com.ssc.demo.jdbc.JDBCTest"/>
loadCustomVfs(settings)方法为:
1 private void loadCustomVfs(Properties props) throws ClassNotFoundException { 2 //得到setting标签 name为vfsImpl的属性值 3 String value = props.getProperty("vfsImpl"); 4 if (value != null) { 5 //将vfsImpl属性值分割组成数组 6 String[] clazzes = value.split(","); 7 for (String clazz : clazzes) { 8 if (!clazz.isEmpty()) { 9 //忽略警告 10 @SuppressWarnings("unchecked") 11 //加载类 12 Class<? extends VFS> vfsImpl = (Class<? extends VFS>)Resources.classForName(clazz); 13 // 将类配置加载到全局配置中 14 configuration.setVfsImpl(vfsImpl); 15 } 16 } 17 } 18 }
settingsElement(settings);加载大部分用户定义配置,方法内容为:
1 private void settingsElement(Properties props) throws Exception { 2 configuration.setAutoMappingBehavior(AutoMappingBehavior.valueOf(props.getProperty("autoMappingBehavior", "PARTIAL"))); 3 configuration.setAutoMappingUnknownColumnBehavior(AutoMappingUnknownColumnBehavior.valueOf(props.getProperty("autoMappingUnknownColumnBehavior", "NONE"))); 4 configuration.setCacheEnabled(booleanValueOf(props.getProperty("cacheEnabled"), true)); 5 configuration.setProxyFactory((ProxyFactory) createInstance(props.getProperty("proxyFactory"))); 6 configuration.setLazyLoadingEnabled(booleanValueOf(props.getProperty("lazyLoadingEnabled"), false)); 7 configuration.setAggressiveLazyLoading(booleanValueOf(props.getProperty("aggressiveLazyLoading"), false)); 8 configuration.setMultipleResultSetsEnabled(booleanValueOf(props.getProperty("multipleResultSetsEnabled"), true)); 9 configuration.setUseColumnLabel(booleanValueOf(props.getProperty("useColumnLabel"), true)); 10 configuration.setUseGeneratedKeys(booleanValueOf(props.getProperty("useGeneratedKeys"), false)); 11 configuration.setDefaultExecutorType(ExecutorType.valueOf(props.getProperty("defaultExecutorType", "SIMPLE"))); 12 configuration.setDefaultStatementTimeout(integerValueOf(props.getProperty("defaultStatementTimeout"), null)); 13 configuration.setDefaultFetchSize(integerValueOf(props.getProperty("defaultFetchSize"), null)); 14 configuration.setMapUnderscoreToCamelCase(booleanValueOf(props.getProperty("mapUnderscoreToCamelCase"), false)); 15 configuration.setSafeRowBoundsEnabled(booleanValueOf(props.getProperty("safeRowBoundsEnabled"), false)); 16 configuration.setLocalCacheScope(LocalCacheScope.valueOf(props.getProperty("localCacheScope", "SESSION"))); 17 configuration.setJdbcTypeForNull(JdbcType.valueOf(props.getProperty("jdbcTypeForNull", "OTHER"))); 18 configuration.setLazyLoadTriggerMethods(stringSetValueOf(props.getProperty("lazyLoadTriggerMethods"), "equals,clone,hashCode,toString")); 19 configuration.setSafeResultHandlerEnabled(booleanValueOf(props.getProperty("safeResultHandlerEnabled"), true)); 20 configuration.setDefaultScriptingLanguage(resolveClass(props.getProperty("defaultScriptingLanguage"))); 21 @SuppressWarnings("unchecked") 22 Class<? extends TypeHandler> typeHandler = (Class<? extends TypeHandler>)resolveClass(props.getProperty("defaultEnumTypeHandler")); 23 configuration.setDefaultEnumTypeHandler(typeHandler); 24 configuration.setCallSettersOnNulls(booleanValueOf(props.getProperty("callSettersOnNulls"), false)); 25 configuration.setUseActualParamName(booleanValueOf(props.getProperty("useActualParamName"), true)); 26 configuration.setReturnInstanceForEmptyRow(booleanValueOf(props.getProperty("returnInstanceForEmptyRow"), false)); 27 configuration.setLogPrefix(props.getProperty("logPrefix")); 28 @SuppressWarnings("unchecked") 29 Class<? extends Log> logImpl = (Class<? extends Log>)resolveClass(props.getProperty("logImpl")); 30 configuration.setLogImpl(logImpl); 31 configuration.setConfigurationFactory(resolveClass(props.getProperty("configurationFactory"))); 32 }
生于忧患,死于安乐