mybatis配置文件解析原理简略时序图

配置文件解析主要用到XMLConfigBuilder(解析mybatis-config.xml) -->  XMLMapperBuilder(解析mapper.xml) --> XMLStatementBuilder(解析mapper.xml中cache, resultMap等配置信息,包括处理sql语句中的include标签) -->XMLScriptBuilder(解析mapper.xml中insert update select delete等sql语句节点)

1. 每个SQL语句节点都会生成一个SqlSource,每个SqlSource中都会保存一个SqlNode,SqlNode中又有子的SqlNode(包括普通sql语句也是一个文本SqlNode(StaticTextSqlNode))

2. 对于每个SQL语句节点,不同Node的解析会使用不同的NodeHandler,XMLScriptBuilder中有一个内部接口NodeHandler,有多个实现类(IfNodeHandler, WhereNodeHandler, ChooseNodeHandler等), 这些实现类的作用就是处理SQL语句节点内部的每种不同的节点标签(如<if></if> <where></where>等)

3. 对于上边红色标示的处理include标签,是在XMLStatementBuilder中来做的,源码:

 1 /**
 2 * XMLStatmentBuilder
 3 */
 4 public void parseStatementNode() {
 5     //...处理属性
 6 
 7     // Include Fragments before parsing 处理include标签
 8     XMLIncludeTransformer includeParser = new XMLIncludeTransformer(configuration, builderAssistant);
 9     includeParser.applyIncludes(context.getNode());
10 
11     // Parse selectKey after includes and remove them. 处理<selectKey>标签
12     processSelectKeyNodes(id, parameterTypeClass, langDriver);
13     
14     // Parse the SQL (pre: <selectKey> and <include> were parsed and removed) 处理SQL语句和内部标签
15     //...
16   }

 

 1 /**
 2 * XMLIncludeTransformer
 3 */
 4 public void applyIncludes(Node source) {
 5     if (source.getNodeName().equals("include")) {
 6       Node toInclude = findSqlFragment(getStringAttribute(source, "refid"));
 7       applyIncludes(toInclude);
 8       if (toInclude.getOwnerDocument() != source.getOwnerDocument()) {
 9         toInclude = source.getOwnerDocument().importNode(toInclude, true);
10       }
11       source.getParentNode().replaceChild(toInclude, source);
12       while (toInclude.hasChildNodes()) {
13         toInclude.getParentNode().insertBefore(toInclude.getFirstChild(), toInclude);
14       }
15       toInclude.getParentNode().removeChild(toInclude);
16     } else if (source.getNodeType() == Node.ELEMENT_NODE) {
17       NodeList children = source.getChildNodes();
18       for (int i=0; i<children.getLength(); i++) {
19         applyIncludes(children.item(i));
20       }
21     }
22   }

 

 1 /**
 2 * XMLStatmentBuilder
 3 */
 4 private void processSelectKeyNodes(String id, Class<?> parameterTypeClass, LanguageDriver langDriver) {
 5     List<XNode> selectKeyNodes = context.evalNodes("selectKey");
 6     if (configuration.getDatabaseId() != null) {
 7       parseSelectKeyNodes(id, selectKeyNodes, parameterTypeClass, langDriver, configuration.getDatabaseId());
 8     }
 9     parseSelectKeyNodes(id, selectKeyNodes, parameterTypeClass, langDriver, null);
10     removeSelectKeyNodes(selectKeyNodes);
11   }

 

posted @ 2016-01-07 18:16  桦沐  阅读(1197)  评论(0编辑  收藏  举报