从底层源码浅析Mybatis初始化过程 (4)

再看一下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); } } }

其中主要的逻辑都在下示图中的两行代码中

从底层源码浅析Mybatis初始化过程

接下来我们进入XMLStatementBuilder类的parseStatementNode去看看

从底层源码浅析Mybatis初始化过程

从底层源码浅析Mybatis初始化过程

最终由MapperBuilderAssistant完成MappedStatement对象的封装,并且将MappedStatement对象放入Configuration对象的mappedStatements容器中

从底层源码浅析Mybatis初始化过程

初始化完成

主要功能 : 将已经装载了各种XML信息的Configuration对象作为参数构建DefaultSqlSessionFactory返回,Mybatis初始化完成!!!

public SqlSessionFactory build(Configuration config) { return new DefaultSqlSessionFactory(config); }

从底层源码浅析Mybatis初始化过程

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpfywf.html