1.MyBatis将整个系统串联起来的就是Configure对象这个需要牢记。在前面MyBatis xml文件解析流程(二) Mapper解析中介绍了Mapper的解析入口,以及Mapper文件中各个节点的解析方法。里面有几个类需要总结下
- BaseBuilder:作为其他Builder类的基类
2.XMLConfigBuilder:在Configuration解析时介绍过,主要用来解析config配置文件下的Configuration节点,内部会使用XMLMapperBuilder用于解析xml文件
3.XMLMapperBuilder:在Mapper解析中也介绍过。主要用来解析Mapper文件的,里面用,内部会使用XMLStatementBuilder来处理节点
4.XMLStatementBuilder:解析select|insert|update|delete节点,内部会使用XMLScriptBuilder解析xml节点
5.XMLScriptBuilder:解析sql中各个其他的节点并把解析结果保存到SqlNode中。
6.MapperBuilderAssistant:这是mapper解析中的关键,他作为mapper解析的助理类,负责将解析出来的结果保存下来,并且通过configuration.addMappedStatement方法保存到conguration对象中,最终在调用dao是根据传入的参数动态生成sql。所以说configuration是MyBatis调用的调配中心。
2.动态sql解析流程分析
2.1 从XMLMapperBuilder类中configurationElement方法是mapper文件解析开始。
private void configurationElement(XNode context) {
try {
String namespace = context.getStringAttribute("namespace");
if (namespace.equals("")) {
throw new BuilderException("Mapper's namespace cannot be empty");
}
builderAssistant.setCurrentNamespace(namespace);
cacheRefElement(context.evalNode("cache-ref"));
cacheElement(context.evalNode("cache"));
parameterMapElement(context.evalNodes("/mapper/parameterMap"));
resultMapElements(context.evalNodes("/mapper/resultMap"));
sqlElement(context.evalNodes("/mapper/sql"));
//sql insert|select|update|delete节点解析入口
buildStatementFromContext(context.evalNodes("select|insert|update|delete"));
} catch (Exception e) {
throw new BuilderException("Error parsing Mapper XML. Cause: " + e, e);
}
}
2.2调用buildStatementFromContext方法,将配置文件中的insert|select|update|delete保存到list集合中,并且通过buildStatementFromContext方法进行循环解析所有节点
private void buildStatementFromContext(List<XNode> list) {
if (configuration.getDatabaseId() != null) {
buildStatementFromContext(list, configuration.getDatabaseId());
}
buildStatementFromContext(list, null);
}
private void buildStatementFromContext(List<XNode> list, String requiredDatabaseId) {
for