mybatis源码阅读-MappedStatement各个属性解析过程(八)
2024-08-31 02:17:13
调用方
类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);
}
}
最新文章
- PHP 位运算(&;, |, ^, ~, <;<;, >;>;)及 PHP错误级别报告设置(error_reporting) 详解
- Cocopod
- 【代码笔记】iOS-浮动的云
- FPGA中的INOUT接口和高阻态
- C#位运算讲解与示例2
- mobiscroll.js 使用
- #linux包之lsof之lsof命令
- Android IOS WebRTC 音视频开发总结(五七)-- 网络传输上的一种QoS方案
- mac 自带 php 验证码 不显示
- mysql 在windows下的安装,开发基础与要点
- Spyder调试错误-";TypeError: decoding Unicode is not supported";
- 分类: LINUX apache 访问设置配置
- web中纯java获取配置文件中的数据
- 用Django Rest Framework和AngularJS开始你的项目
- error: The requested URL returned error: 401 Unauthorized while accessing
- Vivado如何使用命令行创建工程
- linux如何让一个程序崩溃后自动重启
- Beta 冲刺 (6/7)
- 更新ruby:Error running &#39;requirements_osx_brew_update_system ruby-2.4.1报错解决
- js中去掉字符串的空格、回车换行