MyBatis 源码分析 - 映射文件解析过程 (6)

如上流程,第1步和最后一步都是一些常规操作,无需过多解释。第2步和第3步则是接下来需要重点分析的操作,这其中,鉴别器 discriminator 不是很常用的特性,我觉得大家知道它有什么用就行了,所以就不分析了。下面先来分析 <id> 和 <result> 节点的解析逻辑。

2.1.3.1 解析 <id> 和 <result> 节点

在 <resultMap> 节点中,子节点 <id> 和 <result> 都是常规配置,比较常见。相信大家对此也比较熟悉了,我就不多说了。下面我们直接分析这两个节点的解析过程。如下:

private ResultMapping buildResultMappingFromContext(XNode context, Class<?> resultType, List<ResultFlag> flags) throws Exception { String property; // 根据节点类型获取 name 或 property 属性 if (flags.contains(ResultFlag.CONSTRUCTOR)) { property = context.getStringAttribute("name"); } else { property = context.getStringAttribute("property"); } // 获取其他各种属性 String column = context.getStringAttribute("column"); String javaType = context.getStringAttribute("javaType"); String jdbcType = context.getStringAttribute("jdbcType"); String nestedSelect = context.getStringAttribute("select"); /* * 解析 resultMap 属性,该属性出现在 <association> 和 <collection> 节点中。 * 若这两个节点不包含 resultMap 属性,则调用 processNestedResultMappings 方法 * 解析嵌套 resultMap。 */ String nestedResultMap = context.getStringAttribute("resultMap", processNestedResultMappings(context, Collections.<ResultMapping>emptyList())); String notNullColumn = context.getStringAttribute("notNullColumn"); String columnPrefix = context.getStringAttribute("columnPrefix"); String typeHandler = context.getStringAttribute("typeHandler"); String resultSet = context.getStringAttribute("resultSet"); String foreignColumn = context.getStringAttribute("foreignColumn"); boolean lazy = "lazy".equals(context.getStringAttribute("fetchType", configuration.isLazyLoadingEnabled() ? "lazy" : "eager")); // 解析 javaType、typeHandler 的类型以及枚举类型 JdbcType Class<?> javaTypeClass = resolveClass(javaType); Class<? extends TypeHandler<?>> typeHandlerClass = (Class<? extends TypeHandler<?>>) resolveClass(typeHandler); JdbcType jdbcTypeEnum = resolveJdbcType(jdbcType); // 构建 ResultMapping 对象 return builderAssistant.buildResultMapping(resultType, property, column, javaTypeClass, jdbcTypeEnum, nestedSelect, nestedResultMap, notNullColumn, columnPrefix, typeHandlerClass, flags, resultSet, foreignColumn, lazy); }

上面的方法主要用于获取 <id> 和 <result> 节点的属性,其中,resultMap 属性的解析过程要相对复杂一些。该属性存在于 <association> 和 <collection> 节点中。下面以 <association> 节点为例,演示该节点的两种配置方式,分别如下:

第一种配置方式是通过 resultMap 属性引用其他的 <resultMap> 节点,配置如下:

<resultMap type="Article"> <id property="id" column="id"/> <result property="title" column="article_title"/> <!-- 引用 authorResult --> <association property="article_author" column="article_author_id" javaType="Author" resultMap="authorResult"/> </resultMap> <resultMap type="Author"> <id property="id" column="author_id"/> <result property="name" column="author_name"/> </resultMap>

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

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