1. 首先Mybatis会加载配置文件mybatis-config.xml, 主要实现在Mybatis的builder模块,包路径org.apache.ibatis.builder,解析入口XMLConfigBuilder
private void settingsElement(Properties props) {
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.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.setArgNameBasedConstructorAutoMapping(booleanValueOf(props.getProperty("argNameBasedConstructorAutoMapping"), false));
configuration.setDefaultSqlProviderType(resolveClass(props.getProperty("defaultSqlProviderType")));
configuration.setNullableOnForEach(booleanValueOf(props.getProperty("nullableOnForEach"), false));
}
加载配置入口: org.apache.ibatis.builder.xml.XMLConfigBuilder#parseConfiguration
- 加载properties节点 , 将配置中变量加载到mybatis上下文中
- 加载settings节点, 初始化或者定制化configuration中属性
- 加载typeAliases节点, 添加类型别名映射器
- 加载plugins节点, 添加一些插件处理器
- 加载objectFactory节点,指定对象创建工厂类
- 加载objectWrapperFactory节点,指定对象创建工厂类
- 加载reflectorFactory节点,指定对象反射处理工厂类
- 加载environments节点, 定制化环境配置,例如不同环境不同数据库连接配置
- 加载databaseIdProvider节点,获取不同数据源的databaseId
- 加载typeHandlers节点, 添加类型处理器
- 加载mappers节点,添加Mapper
蒋加载的配置信息统计存储在org.apache.ibatis.session.Configuration
2. Mybatis加载具体的Mapper.xml文件,XMLMapperBuilder
加载配置入口: org.apache.ibatis.builder.xml.XMLMapperBuilder#parse
1. org.apache.ibatis.builder.xml.XMLMapperBuilder#configurationElement 加载Mapper节点配置
- 获取namespace属性, 设置namespace
- 加载cache-ref节点配置, 加载缓存配置
- 加载cache节点配置, 加载缓存配置,MapperBuilderAssistant#useNewCache
- 加载/mapper/parameterMap节点配置, 加载ParameterMapping配置
- 加载ResultMapping配置,MapperBuilderAssistant#buildParameterMapping
- 加载/mapper/resultMap节点配置, 加载ResultMapping配置,MapperBuilderAssistant#buildResultMapping
- 加载/mapper/sql节点配置, 加载sql配置
- 加载select|insert|update|delete节点配置, 构造MappedStatement配置, org.apache.ibatis.builder.xml.XMLStatementBuilder#parseStatementNode
2. org.apache.ibatis.builder.xml.XMLMapperBuilder#bindMapperForNamespace 将xml文件配置的具体java接口注册到MapperRegistry
- org.apache.ibatis.session.Configuration#addMapper
- org.apache.ibatis.binding.MapperRegistry#addMapper
3. XMLMapperBuilder#parsePendingResultMaps 加载未解析成功的ResultMapping配置
4. XMLMapperBuilder#parsePendingCacheRefs 加载上面为解析成功的Cache配置
5. XMLMapperBuilder#parsePendingStatements 加载上面为解析成功的MappedStatement配置
3. Mybatis加载mapper文件中具体的某个SQL语句,XMLStatementBuilder
解析入口: org.apache.ibatis.builder.xml.XMLStatementBuilder#parseStatementNode
- 构建sql语句即 SqlSource 对象,LanguageDriver#createSqlSource
- 构建MapperStatement, MapperBuilderAssistant#addMappedStatement()
4. Mybatis构建SqlSource对象,org.apache.ibatis.scripting.LanguageDriver
接口: org.apache.ibatis.scripting.LanguageDriver
实现:
org.apache.ibatis.scripting.xmltags.XMLLanguageDriver
org.apache.ibatis.scripting.defaults.RawLanguageDriver接口: org.apache.ibatis.scripting.xmltags.SqlNode sql节点
实现:
org.apache.ibatis.scripting.xmltags.ChooseSqlNode
org.apache.ibatis.scripting.xmltags.ForEachSqlNode
org.apache.ibatis.scripting.xmltags.IfSqlNode
org.apache.ibatis.scripting.xmltags.MixedSqlNode
org.apache.ibatis.scripting.xmltags.SetSqlNode
org.apache.ibatis.scripting.xmltags.TrimSqlNode
org.apache.ibatis.scripting.xmltags.WhereSqlNode 等等接口: org.apache.ibatis.scripting.xmltags.XMLScriptBuilder.NodeHandler 节点处理器
org.apache.ibatis.scripting.xmltags.XMLScriptBuilder.BindHandler
org.apache.ibatis.scripting.xmltags.XMLScriptBuilder.WhereHandler
org.apache.ibatis.scripting.xmltags.XMLScriptBuilder.SetHandler
org.apache.ibatis.scripting.xmltags.XMLScriptBuilder.ChooseHandler等等
解析入口:XMLLanguageDriver#createSqlSource
1. org.apache.ibatis.scripting.xmltags.XMLScriptBuilder#parseScriptNode
- org.apache.ibatis.scripting.xmltags.DynamicSqlSource
- org.apache.ibatis.scripting.defaults.RawSqlSource