mybatis源码阅读-MappedStatement各个属性解析过程(八)
调用方
类org.apache.ibatis.builder.xml.XMLMapperBuilder
private void configurationElement(XNode context) {
try {
String namespace = context.getStringAttribute("namespace");
if (namespace != null && !namespace.equals("")) {
this.builderAssistant.setCurrentNamespace(namespace);
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"));
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);
}
}
解析ParameterMap
表现形式
<parameterMap class="com.ibatis.dataobject.Product" id="insert-product-param" >
<parameter property="id"/>
<parameter property="description"/>
<parameter property="price"/>
</parameterMap>
<statement id="insertProduct-useParaMap" parameterMap="insert-product-param">
<![CDATA[insert into t_product(prd_id,prd_description,prd_price) values(?,?,?)]]>
</statement>
源码
private void parameterMapElement(List<XNode> list) throws Exception {
Iterator i$ = list.iterator();
//循环解析所有ParameterMap
while(i$.hasNext()) {
XNode parameterMapNode = (XNode)i$.next();
String id = parameterMapNode.getStringAttribute("id");
String type = parameterMapNode.getStringAttribute("type");
Class<?> parameterClass = this.resolveClass(type);
List<XNode> parameterNodes = parameterMapNode.evalNodes("parameter");
List<ParameterMapping> parameterMappings = new ArrayList();
Iterator i$ = parameterNodes.iterator();
//解析里面的parameter节点封装成parameterMapping对象
while(i$.hasNext()) {
XNode parameterNode = (XNode)i$.next();
String property = parameterNode.getStringAttribute("property");
String javaType = parameterNode.getStringAttribute("javaType");
String jdbcType = parameterNode.getStringAttribute("jdbcType");
String resultMap = parameterNode.getStringAttribute("resultMap");
String mode = parameterNode.getStringAttribute("mode");
String typeHandler = parameterNode.getStringAttribute("typeHandler");
Integer numericScale = parameterNode.getIntAttribute("numericScale");
ParameterMode modeEnum = this.resolveParameterMode(mode);
Class<?> javaTypeClass = this.resolveClass(javaType);
JdbcType jdbcTypeEnum = this.resolveJdbcType(jdbcType);
Class<? extends TypeHandler<?>> typeHandlerClass = this.resolveClass(typeHandler);
ParameterMapping parameterMapping = this.builderAssistant.buildParameterMapping(parameterClass, property, javaTypeClass, jdbcTypeEnum, resultMap, modeEnum, typeHandlerClass, numericScale);
parameterMappings.add(parameterMapping);
}
//内部创建成ParameterMap对象 将parameterMappings设置到属性里面
this.builderAssistant.addParameterMap(id, parameterClass, parameterMappings);
}
}
public ParameterMap addParameterMap(String id, Class<?> parameterClass, List<ParameterMapping> parameterMappings) {
id = this.applyCurrentNamespace(id, false);
//创建ParameterMap并添加到configuration
ParameterMap parameterMap = (new ParameterMap.Builder(this.configuration, id, parameterClass, parameterMappings)).build();
this.configuration.addParameterMap(parameterMap);
return parameterMap;
}
解析ResultMap
跟paramterMap解析很相似 但是resultMap有extend功能
表现形式
<resultMap id="simpleType" type="com.liqiang.entity.Classes">
<id property="id" column="id" /> </resultMap>
<resultMap id="studentMap" type="com.liqiang.entity.Classes" extends="simpleType">
<result property="name" column="name" />
</resultMap>
源码
private ResultMap resultMapElement(XNode resultMapNode, List<ResultMapping> additionalResultMappings) throws Exception {
ErrorContext.instance().activity("processing " + resultMapNode.getValueBasedIdentifier());
String id = resultMapNode.getStringAttribute("id", resultMapNode.getValueBasedIdentifier());
String type = resultMapNode.getStringAttribute("type", resultMapNode.getStringAttribute("ofType", resultMapNode.getStringAttribute("resultType", resultMapNode.getStringAttribute("javaType"))));
//判断是否有继承
String extend = resultMapNode.getStringAttribute("extends");
Boolean autoMapping = resultMapNode.getBooleanAttribute("autoMapping");
Class<?> typeClass = this.resolveClass(type);
Discriminator discriminator = null;
List<ResultMapping> resultMappings = new ArrayList();
resultMappings.addAll(additionalResultMappings);
List<XNode> resultChildren = resultMapNode.getChildren();
Iterator i$ = resultChildren.iterator();
while(i$.hasNext()) {
XNode resultChild = (XNode)i$.next();
if ("constructor".equals(resultChild.getName())) {
this.processConstructorElement(resultChild, typeClass, resultMappings);
} else if ("discriminator".equals(resultChild.getName())) {
discriminator = this.processDiscriminatorElement(resultChild, typeClass, resultMappings);
} else {
List<ResultFlag> flags = new ArrayList();
if ("id".equals(resultChild.getName())) {
flags.add(ResultFlag.ID);
}
resultMappings.add(this.buildResultMappingFromContext(resultChild, typeClass, flags));
}
}
//内部会解析将extend的标签元素整合进来创建一个新的resultMap
ResultMapResolver resultMapResolver = new ResultMapResolver(this.builderAssistant, id, typeClass, extend, discriminator, resultMappings, autoMapping);
try {
return resultMapResolver.resolve();
} catch (IncompleteElementException var14) {
this.configuration.addIncompleteResultMap(resultMapResolver);
throw var14;
}
}
解析"select|insert|update|delete"元素
public void parseStatementNode() {
String id = this.context.getStringAttribute("id");
String databaseId = this.context.getStringAttribute("databaseId");
if (this.databaseIdMatchesCurrent(id, databaseId, this.requiredDatabaseId)) {
Integer fetchSize = this.context.getIntAttribute("fetchSize");
Integer timeout = this.context.getIntAttribute("timeout");
String parameterMap = this.context.getStringAttribute("parameterMap");
String parameterType = this.context.getStringAttribute("parameterType");
Class<?> parameterTypeClass = this.resolveClass(parameterType);
String resultMap = this.context.getStringAttribute("resultMap");
String resultType = this.context.getStringAttribute("resultType");
String lang = this.context.getStringAttribute("lang");
LanguageDriver langDriver = this.getLanguageDriver(lang);
Class<?> resultTypeClass = this.resolveClass(resultType);
String resultSetType = this.context.getStringAttribute("resultSetType");
StatementType statementType = StatementType.valueOf(this.context.getStringAttribute("statementType", StatementType.PREPARED.toString()));
ResultSetType resultSetTypeEnum = this.resolveResultSetType(resultSetType);
String nodeName = this.context.getNode().getNodeName();
SqlCommandType sqlCommandType = SqlCommandType.valueOf(nodeName.toUpperCase(Locale.ENGLISH));
boolean isSelect = sqlCommandType == SqlCommandType.SELECT;
boolean flushCache = this.context.getBooleanAttribute("flushCache", !isSelect).booleanValue();
boolean useCache = this.context.getBooleanAttribute("useCache", isSelect).booleanValue();
boolean resultOrdered = this.context.getBooleanAttribute("resultOrdered", false).booleanValue();
XMLIncludeTransformer includeParser = new XMLIncludeTransformer(this.configuration, this.builderAssistant);
includeParser.applyIncludes(this.context.getNode());
this.processSelectKeyNodes(id, parameterTypeClass, langDriver);
SqlSource sqlSource = langDriver.createSqlSource(this.configuration, this.context, parameterTypeClass);
String resultSets = this.context.getStringAttribute("resultSets");
String keyProperty = this.context.getStringAttribute("keyProperty");
String keyColumn = this.context.getStringAttribute("keyColumn");
String keyStatementId = id + "!selectKey";
keyStatementId = this.builderAssistant.applyCurrentNamespace(keyStatementId, true);
Object keyGenerator;
if (this.configuration.hasKeyGenerator(keyStatementId)) {
keyGenerator = this.configuration.getKeyGenerator(keyStatementId);
} else {
keyGenerator = this.context.getBooleanAttribute("useGeneratedKeys", this.configuration.isUseGeneratedKeys() && SqlCommandType.INSERT.equals(sqlCommandType)).booleanValue() ? new Jdbc3KeyGenerator() : new NoKeyGenerator();
}
//最终根据namesppace+id为key封装成MappedStatement保存到Configuration
this.builderAssistant.addMappedStatement(id, sqlSource, statementType, sqlCommandType, fetchSize, timeout, parameterMap, parameterTypeClass, resultMap, resultTypeClass, resultSetTypeEnum, flushCache, useCache, resultOrdered, (KeyGenerator)keyGenerator, keyProperty, keyColumn, databaseId, langDriver, resultSets);
}
}
mybatis源码阅读-MappedStatement各个属性解析过程(八)的更多相关文章
- Mybatis源码阅读-配置文件及映射文件解析
Mybatis源码分析: 1.配置文件解析: 1.1源码阅读入口: org.apache.ibatis.builder.xml.XMLConfigBuilder.parse(); 功能:解析全局配置文 ...
- mybatis源码阅读-初始化六个工具(六)
六个基本工具图集 图片来源:https://my.oschina.net/zudajun/blog/668596 ObjectFactory 类图 接口定义 public interface Obje ...
- mybatis源码阅读-初始化过程(七)
说明 mybatis初始化过程 就是解析xml到封装成Configuration对象 供后续使用 SqlSessionFactoryBuilder 代码例子 SqlSessionFactoryBuil ...
- Mybatis源码阅读 之 玩转Executor
承接上篇博客, 本文探究MyBatis中的Executor, 如下图: 是Executor体系图 本片博客的目的就是探究如上图中从顶级接口Executor中拓展出来的各个子执行器的功能,以及进一步了解 ...
- mybatis源码分析之02配置文件解析
该篇正式开始学习mybatis的源码,本篇主要学习mybatis是如何加载配置文件mybatis-config.xml的, 先从测试代码入手. public class V1Test { public ...
- 浩哥解析MyBatis源码(十一)——Parsing解析模块之通用标记解析器(GenericTokenParser)与标记处理器(TokenHandler)
原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6724223.html 1.回顾 上面的几篇解析了类型模块,在MyBatis中类型模块包含的 ...
- mybatis源码阅读心得
第一天阅读源码及创建时序图.(第一次用prosson画时序图,挺丑..) 1. 调用 SqlSessionFactoryBuilder 对象的 build(inputStream) 方法: 2. ...
- mybatis源码阅读(动态代理)
这一篇文章主要是记录Mybatis的动态代理学习成果,如果对源码感兴趣,可以看一下上篇文章 https://www.cnblogs.com/ChoviWu/p/10118051.html 阅读本篇的 ...
- mybatis源码阅读-SqlSessionFactory和SqlSession(三)
说明 读了3遍:https://my.oschina.net/zudajun/blog/665956 现在统一整理成笔记 并跟着源码一行一行调试 统一整理起来 SqlSession 接口定义 publ ...
随机推荐
- bag of words in c++
#include <iostream> #include <vector> #include <cstddef> #include <string> # ...
- node.js的模块引用
1.模块的引用示例 var math = require(‘math’): 在common.js规范中,存在require()方法,这个方法接受模块标识,此引引入一个模块的api ...
- [Swift通天遁地]六、智能布局-(1)给视图添加尺寸和中心点的约束
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...
- Vue.js经典开源项目汇总-前端参考资源
Vue.js经典开源项目汇总 原文链接:http://www.cnblogs.com/huyong/p/6517949.html Vue是什么? Vue.js(读音 /vjuː/, 类似于 view) ...
- php三方网站使用微信公众号推送文章
//获取accesstoken 的方法public function index(){ $appId = 'wxd0e50fe967dccccc'; $appSecret = 'd7f6be12ce4 ...
- Flume 是什么?
Flume是一个分布式.可靠.和高可用的海量日志聚合的系统,支持在系统中定制各类数据发送方,用于收集数据:同时,Flume提供对数据进行简单处理,并写到各种数据接受方(可定制)的能力. 收集.聚合事件 ...
- Linq学习(五)-多表连接
本将主要介绍 内连接与 外连接 1.join Linq to sql from a in Blog_Users join b in Blog_UserInfo on a.UserId equals b ...
- Java_注解之二
在上一次的注解案例里面配置注解的同时,也添加了一对多(@OneToMany)的关系在里面. 本次将补充上次的缺失:其他三种关联方式的配置. 为了简化配置的复杂度 在此案例中Emp和Dept并不是唯 ...
- [ HNOI 2006 ] 公路修建问题
\(\\\) \(Description\) 一个\(N\)个点\(M\)条边的图,每条边可以选择\(w_i,p_i\)两个边权之一,现求一个生成树上的最大边权最小值,要求这棵生成树上至少有\(K\) ...
- RTL Compiler之Example
Synthesis = Translation + Logic Optimization + Mapping Step 1 Source files 1) make directory mkdir ...