再看一下mapperParser.parse();
public void parse() { //如果映射文件没有被加载过 if (!this.configuration.isResourceLoaded(this.resource)) { //执行加载映射文件XML方法configurationElement this.configurationElement(this.parser.evalNode("/mapper")); //将此映射文件添加已经解析了的集合中 this.configuration.addLoadedResource(this.resource); //绑定Namespace this.bindMapperForNamespace(); } this.parsePendingResultMaps(); this.parsePendingCacheRefs(); this.parsePendingStatements(); }下面是具体Mybatis解析映射文件中的Statement的过程
private void configurationElement(XNode context) { try { //获取namespace String namespace = context.getStringAttribute("namespace"); //判断namespace,如果为空直接抛出异常 if (namespace != null && !namespace.equals("")) { //设置namespace this.builderAssistant.setCurrentNamespace(namespace); //下面就是解析各个Statement中的各个XML节点 this.cacheRefElement(context.evalNode("cache-ref")); this.cacheElement(context.evalNode("cache")); this.parameterMapElement(context.evalNodes("/mapper/parameterMap")); this.resultMapElements(context.evalNodes("/mapper/resultMap")); this.sqlElement(context.evalNodes("/mapper/sql")); //第三步 : 解析Statement声明 核心方法 this.buildStatementFromContext(context.evalNodes("select|insert|update|delete")); } else { throw new BuilderException("Mapper's namespace cannot be empty"); } } catch (Exception var3) { throw new BuilderException("Error parsing Mapper XML. Cause: " + var3, var3); } }从上述代码中可以看到,XMLMapperBuilder借助MapperBuilderAssistant会对Mapper映射文件进行解析,在解析到最后,会将每一个中的节点解析为MappedStatement对象
第三步 : 解析映射文件的Statement为MappedStatement对象this.buildStatementFromContext(context.evalNodes("select|insert|update|delete"));
主要功能 : 将映射文件的子节点解析为MappedStatement对象
我们进入 this.buildStatementFromContext(context.evalNodes("select|insert|update|delete"));这个方法看一下
private void buildStatementFromContext(List<XNode> list) { if (this.configuration.getDatabaseId() != null) { this.buildStatementFromContext(list, this.configuration.getDatabaseId()); } this.buildStatementFromContext(list, (String)null); } private void buildStatementFromContext(List<XNode> list, String requiredDatabaseId) { Iterator var3 = list.iterator(); while(var3.hasNext()) { XNode context = (XNode)var3.next(); XMLStatementBuilder statementParser = new XMLStatementBuilder(this.configuration, this.builderAssistant, context, requiredDatabaseId); try { statementParser.parseStatementNode(); } catch (IncompleteElementException var7) { this.configuration.addIncompleteStatement(statementParser); } } }其中主要的逻辑都在下示图中的两行代码中
接下来我们进入XMLStatementBuilder类的parseStatementNode去看看
最终由MapperBuilderAssistant完成MappedStatement对象的封装,并且将MappedStatement对象放入Configuration对象的mappedStatements容器中
初始化完成主要功能 : 将已经装载了各种XML信息的Configuration对象作为参数构建DefaultSqlSessionFactory返回,Mybatis初始化完成!!!
public SqlSessionFactory build(Configuration config) { return new DefaultSqlSessionFactory(config); }