配置文件加载(初始化)
主要涉及com.ibatis.sqlmap.engine.builder.xml包下的SqlMapConfigParser、SqlMapParser、SqlStatementParser、XmlParserState、XMLSqlSource
当调用SqlMapClientBuilder.buildSqlMapClient(Reader reader)获取SqlMapClient时,return new SqlMapConfigParser().parse(reader);
1、开始对配置进行分析加载,首先是SqlMapConfigParser类,主要加载一些全局配置,如cacheModelsEnabled、useColumnLabel、defaultStatementTimeout。
private void addSettingsNodelets() { parser.addNodelet("/sqlMapConfig/settings", new Nodelet() { public void process(Node node) throws Exception { Properties attributes = NodeletUtils.parseAttributes(node, state.getGlobalProps()); SqlMapConfiguration config = state.getConfig(); String classInfoCacheEnabledAttr = attributes.getProperty("classInfoCacheEnabled"); boolean classInfoCacheEnabled = (classInfoCacheEnabledAttr == null || "true".equals(classInfoCacheEnabledAttr)); config.setClassInfoCacheEnabled(classInfoCacheEnabled); String lazyLoadingEnabledAttr = attributes.getProperty("lazyLoadingEnabled"); boolean lazyLoadingEnabled = (lazyLoadingEnabledAttr == null || "true".equals(lazyLoadingEnabledAttr)); config.setLazyLoadingEnabled(lazyLoadingEnabled); String statementCachingEnabledAttr = attributes.getProperty("statementCachingEnabled"); boolean statementCachingEnabled = (statementCachingEnabledAttr == null || "true".equals(statementCachingEnabledAttr)); config.setStatementCachingEnabled(statementCachingEnabled); String cacheModelsEnabledAttr = attributes.getProperty("cacheModelsEnabled"); boolean cacheModelsEnabled = (cacheModelsEnabledAttr == null || "true".equals(cacheModelsEnabledAttr)); config.setCacheModelsEnabled(cacheModelsEnabled); String enhancementEnabledAttr = attributes.getProperty("enhancementEnabled"); boolean enhancementEnabled = (enhancementEnabledAttr == null || "true".equals(enhancementEnabledAttr)); config.setEnhancementEnabled(enhancementEnabled); String useColumnLabelAttr = attributes.getProperty("useColumnLabel"); boolean useColumnLabel = (useColumnLabelAttr == null || "true".equals(useColumnLabelAttr)); config.setUseColumnLabel(useColumnLabel); String forceMultipleResultSetSupportAttr = attributes.getProperty("forceMultipleResultSetSupport"); boolean forceMultipleResultSetSupport = "true".equals(forceMultipleResultSetSupportAttr); config.setForceMultipleResultSetSupport(forceMultipleResultSetSupport); String defaultTimeoutAttr = attributes.getProperty("defaultStatementTimeout"); Integer defaultTimeout = defaultTimeoutAttr == null ? null : Integer.valueOf(defaultTimeoutAttr); config.setDefaultStatementTimeout(defaultTimeout); String useStatementNamespacesAttr = attributes.getProperty("useStatementNamespaces"); boolean useStatementNamespaces = "true".equals(useStatementNamespacesAttr); state.setUseStatementNamespaces(useStatementNamespaces); } }); }
2、如果分析 到/sqlMapConfig/sqlMap时,则调用SqlMapParser进行分析sql映射配置
SqlMapParser会加载sqlMap中的resultMap、parameterMap等自定义的对象的配置
parser.addNodelet("/sqlMap/select", new Nodelet() { public void process(Node node) throws Exception { statementParser.parseGeneralStatement(node, new SelectStatement()); } });
3、具体的sql语句(/sqlMap/select等节点)会调用SqlStatementParser进行加载,放到XMLSqlSource中,构造一个MappedStatementConfig,存储 MappedStatement,参数类型、返回结果类型等配置
public void parseGeneralStatement(Node node, MappedStatement statement) { // get attributes Properties attributes = NodeletUtils.parseAttributes(node, state.getGlobalProps()); String id = attributes.getProperty("id"); String parameterMapName = state.applyNamespace(attributes.getProperty("parameterMap")); String parameterClassName = attributes.getProperty("parameterClass"); String resultMapName = attributes.getProperty("resultMap"); String resultClassName = attributes.getProperty("resultClass"); String cacheModelName = state.applyNamespace(attributes.getProperty("cacheModel")); String xmlResultName = attributes.getProperty("xmlResultName"); String resultSetType = attributes.getProperty("resultSetType"); String fetchSize = attributes.getProperty("fetchSize"); String allowRemapping = attributes.getProperty("remapResults"); String timeout = attributes.getProperty("timeout"); if (state.isUseStatementNamespaces()) { id = state.applyNamespace(id); } String[] additionalResultMapNames = null; if (resultMapName != null) { additionalResultMapNames = state.getAllButFirstToken(resultMapName); resultMapName = state.getFirstToken(resultMapName); resultMapName = state.applyNamespace(resultMapName); for (int i = 0; i < additionalResultMapNames.length; i++) { additionalResultMapNames[i] = state.applyNamespace(additionalResultMapNames[i]); } } String[] additionalResultClassNames = null; if (resultClassName != null) { additionalResultClassNames = state.getAllButFirstToken(resultClassName); resultClassName = state.getFirstToken(resultClassName); } Class[] additionalResultClasses = null; if (additionalResultClassNames != null) { additionalResultClasses = new Class[additionalResultClassNames.length]; for (int i = 0; i < additionalResultClassNames.length; i++) { additionalResultClasses[i] = resolveClass(additionalResultClassNames[i]); } } state.getConfig().getErrorContext().setMoreInfo("Check the parameter class."); Class parameterClass = resolveClass(parameterClassName); state.getConfig().getErrorContext().setMoreInfo("Check the result class."); Class resultClass = resolveClass(resultClassName); Integer timeoutInt = timeout == null ? null : new Integer(timeout); Integer fetchSizeInt = fetchSize == null ? null : new Integer(fetchSize); boolean allowRemappingBool = "true".equals(allowRemapping); MappedStatementConfig statementConf = state.getConfig().newMappedStatementConfig(id, statement, new XMLSqlSource(state, node), parameterMapName, parameterClass, resultMapName, additionalResultMapNames, resultClass, additionalResultClasses, resultSetType, fetchSizeInt, allowRemappingBool, timeoutInt, cacheModelName, xmlResultName); findAndParseSelectKey(node, statementConf); }
所有的配置加载过程中都用到一个XmlParserState,些类中包含一个SqlMapConfiguration还有多个Properties,用于存储所有的配置信息
XML配置文件分析主要用到一个类NodeletParser,调用SqlMapConfigParser、SqlMapParser提供的处理方法process()