本章中分析update元素的解析。
1 配置文件
<update id="updateByPrimaryKeySelective" parameterType="cn.vansky.schedule.time.menu.bo.Menu">
<!--
WARNING - @mbggenerated
This element is automatically generated by MyBatis Generator, do not modify.
This element was generated on Fri Aug 14 16:08:36 CST 2015.
-->
update tb_menu
<set>
<if test="menuName != null">
menu_name = #{menuName,jdbcType=VARCHAR},
</if>
<if test="menuRemark != null">
menu_remark = #{menuRemark,jdbcType=VARCHAR},
</if>
<if test="menuParentId != null">
menu_parent_id = #{menuParentId,jdbcType=INTEGER},
</if>
<if test="menuUrl != null">
menu_url = #{menuUrl,jdbcType=VARCHAR},
</if>
<if test="isShow != null">
is_show = #{isShow,jdbcType=TINYINT},
</if>
<if test="isDelete != null">
is_delete = #{isDelete,jdbcType=TINYINT},
</if>
<if test="operationUserName != null">
operation_user_name = #{operationUserName,jdbcType=VARCHAR},
</if>
<if test="operationTime != null">
operation_time = #{operationTime,jdbcType=TIMESTAMP},
</if>
</set>
where Id = #{id,jdbcType=INTEGER}
</update>
2 方法parseStatementNode
public void parseStatementNode() {
// updateByPrimaryKeySelective
String id = context.getStringAttribute("id");
// null
String databaseId = context.getStringAttribute("databaseId");
// 第一次检查这里是不通过的,直接跳过
if (!databaseIdMatchesCurrent(id, databaseId, this.requiredDatabaseId)) return;
// null
Integer fetchSize = context.getIntAttribute("fetchSize");
// null
Integer timeout = context.getIntAttribute("timeout");
// null
String parameterMap = context.getStringAttribute("parameterMap");
// cn.vansky.schedule.time.menu.bo.Menu
String parameterType = context.getStringAttribute("parameterType");
// class cn.vansky.schedule.time.menu.bo.Menu
Class<?> parameterTypeClass = resolveClass(parameterType);
// null
String resultMap = context.getStringAttribute("resultMap");
// null
String resultType = context.getStringAttribute("resultType");
// null
String lang = context.getStringAttribute("lang");
// 获取默认的处理对象
// org.apache.ibatis.scripting.xmltags.XMLLanguageDriver
LanguageDriver langDriver = getLanguageDriver(lang);
// null
Class<?> resultTypeClass = resolveClass(resultType);
// null
String resultSetType = context.getStringAttribute("resultSetType");
// PREPARED
StatementType statementType = StatementType.valueOf(context.getStringAttribute("statementType", StatementType.PREPARED.toString()));
// null
ResultSetType resultSetTypeEnum = resolveResultSetType(resultSetType);
// update
String nodeName = context.getNode().getNodeName();
// UPDATE
SqlCommandType sqlCommandType = SqlCommandType.valueOf(nodeName.toUpperCase(Locale.ENGLISH));
// false
boolean isSelect = sqlCommandType == SqlCommandType.SELECT;
// true
boolean flushCache = context.getBooleanAttribute("flushCache", !isSelect);
// false
boolean useCache = context.getBooleanAttribute("useCache", isSelect);
// false
boolean resultOrdered = context.getBooleanAttribute("resultOrdered", false);
// Include Fragments before parsing
XMLIncludeTransformer includeParser = new XMLIncludeTransformer(configuration, builderAssistant);
// 解析<include refid="Base_Column_List" />
includeParser.applyIncludes(context.getNode());
// Parse selectKey after includes and remove them.
processSelectKeyNodes(id, parameterTypeClass, langDriver);
// 这里很明显也是动态SQL
// org.apache.ibatis.scripting.xmltags.DynamicSqlSource
SqlSource sqlSource = langDriver.createSqlSource(configuration, context, parameterTypeClass);
// null
String resultSets = context.getStringAttribute("resultSets");
// null
String keyProperty = context.getStringAttribute("keyProperty");
// null
String keyColumn = context.getStringAttribute("keyColumn");
// org.apache.ibatis.executor.keygen.NoKeyGenerator
KeyGenerator keyGenerator;
// updateByPrimaryKeySelective!selectKey
String keyStatementId = id + SelectKeyGenerator.SELECT_KEY_SUFFIX;
// cn.vansky.schedule.time.menu.dao.MenuMapper.updateByPrimaryKeySelective!selectKey
keyStatementId = builderAssistant.applyCurrentNamespace(keyStatementId, true);
if (configuration.hasKeyGenerator(keyStatementId)) {
keyGenerator = configuration.getKeyGenerator(keyStatementId);
} else {
keyGenerator = context.getBooleanAttribute("useGeneratedKeys",
configuration.isUseGeneratedKeys() && SqlCommandType.INSERT.equals(sqlCommandType))
? new Jdbc3KeyGenerator() : new NoKeyGenerator();
}
builderAssistant.addMappedStatement(id, sqlSource, statementType, sqlCommandType,
fetchSize, timeout, parameterMap, parameterTypeClass, resultMap, resultTypeClass,
resultSetTypeEnum, flushCache, useCache, resultOrdered,
keyGenerator, keyProperty, keyColumn, databaseId, langDriver, resultSets);
}
updateByPrimaryKeySelective最终的MappedStatement
下面就来看动态SqlSource的属性。