XMLMapperBuilder.parse()方法
XMLConfigBuilder在解析过程中碰到mappers元素会交由XMLMapperBuilder.parse()方法来处理
public void parse() {
if (!configuration.isResourceLoaded(resource)) {
//真正解析
configurationElement(parser.evalNode("/mapper"));
configuration.addLoadedResource(resource);
bindMapperForNamespace();
}
parsePendingResultMaps();
parsePendingChacheRefs();
parsePendingStatements();
}
private void configurationElement(XNode context) {
try {
String namespace = context.getStringAttribute("namespace");
//在Mybatis3中mapper元素必须定义命名空间
if (namespace.equals("")) {
throw new BuilderException("Mapper's namespace cannot be empty");
}
builderAssistant.setCurrentNamespace(namespace);
//缓存,以后再看
cacheRefElement(context.evalNode("cache-ref"));
cacheElement(context.evalNode("cache"));
//解析parameterMap节点,Mybatis3中官方已经不推荐使用parameterMap配置,这里也不做讨论
parameterMapElement(context.evalNodes("/mapper/parameterMap"));
//解析resultMap
resultMapElements(context.evalNodes("/mapper/resultMap"));
sqlElement(context.evalNodes("/mapper/sql"));
//解析sql
buildStatementFromContext(context.evalNodes("select|insert|update|delete"));
} catch (Exception e) {
throw new BuilderException("Error parsing Mapper XML. Cause: " + e, e);
}
}
解析resultMap节点
private ResultMap resultMapElement(XNode resultMapNode, List<ResultMapping> additionalResultMappings) throws Exception {
ErrorContext.instance().activity("processing " + resultMapNode.getValueBasedIdentifier());
//id,对应ResultMap.id,内映射没有ID,用<span style="font-family: Arial, Helvetica, sans-serif; font-size: 12px;">resultMapNode.getValueBasedIdentifier()方法生成一个</span>
String id = resultMapNode.getStringAttribute("id",
resultMapNode.getValueBasedIdentifier());
//type,对应ResultMap.Type,这里可以看到这个type可以通过很多个属性进行配置
String type = resultMapNode.getStringAttribute("type",
resultMapNode.getStringAttribute("ofType",
resultMapNode.getStringAttribute("resultType",
resultMapNode.getStringAttribute("javaType"))));
String extend = resultMapNode.getStringAt