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

上面干巴巴的描述不够直观。下面我们写点代码测试一下,并把这些集合的内容打印到控制台上,大家直观感受一下。先定义一个映射文件,如下:

<mapper namespace="xyz.coolblog.dao.ArticleDao"> <resultMap type="xyz.coolblog.model.Article"> <constructor> <idArg column="id"/> <arg column="title"/> <arg column="content"/> </constructor> <id property="id" column="id"/> <result property="author" column="author"/> <result property="createTime" column="create_time"/> </resultMap> </mapper>

测试代码如下:

public class ResultMapTest { @Test public void printResultMapInfo() throws Exception { Configuration configuration = new Configuration(); String resource = "mapper/ArticleMapper.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); XMLMapperBuilder builder = new XMLMapperBuilder(inputStream, configuration, resource, configuration.getSqlFragments()); builder.parse(); ResultMap resultMap = configuration.getResultMap("articleResult"); System.out.println("\n-------------------+✨ mappedColumns ✨+--------------------"); System.out.println(resultMap.getMappedColumns()); System.out.println("\n------------------+✨ mappedProperties ✨+------------------"); System.out.println(resultMap.getMappedProperties()); System.out.println("\n------------------+✨ idResultMappings ✨+------------------"); resultMap.getIdResultMappings().forEach(rm -> System.out.println(simplify(rm))); System.out.println("\n---------------+✨ propertyResultMappings ✨+---------------"); resultMap.getPropertyResultMappings().forEach(rm -> System.out.println(simplify(rm))); System.out.println("\n-------------+✨ constructorResultMappings ✨+--------------"); resultMap.getConstructorResultMappings().forEach(rm -> System.out.println(simplify(rm))); System.out.println("\n-------------------+✨ resultMappings ✨+-------------------"); resultMap.getResultMappings().forEach(rm -> System.out.println(simplify(rm))); inputStream.close(); } /** 简化 ResultMapping 输出结果 */ private String simplify(ResultMapping resultMapping) { return String.format("ResultMapping{column='%s', property='%s', flags=%s, ...}", resultMapping.getColumn(), resultMapping.getProperty(), resultMapping.getFlags()); } }

这里,我们把5个集合转给你的内容都打印出来,结果如下:

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

如上,结果比较清晰明了,不需要过多解释了。我们参照上面配置文件及输出的结果,把 ResultMap 的大致轮廓画出来。如下:

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

到这里,<resultMap> 节点的解析过程就分析完了。总的来说,该节点的解析过程还是比较复杂的。好了,其他的就不多说了,继续后面的分析。

2.1.4 解析 <sql> 节点

<sql> 节点用来定义一些可重用的 SQL 语句片段,比如表名,或表的列名等。在映射文件中,我们可以通过 <include> 节点引用 <sql> 节点定义的内容。下面我来演示一下 <sql> 节点的使用方式,如下:

<sql> article </sql> <select resultType="Article"> SELECT id, title FROM <include refid="table"/> WHERE id = #{id} </select> <update parameterType="Article"> UPDATE <include refid="table"/> SET title = #{title} WHERE id = #{id} </update>

如上,上面配置中,<select> 和 <update> 节点通过 <include> 引入定义在 <sql> 节点中的表名。上面的配置比较常规,除了静态文本,<sql> 节点还支持属性占位符 ${}。比如:

<sql> ${table_prefix}_article </sql>

如果属性 table_prefix = blog,那么 <sql> 节点中的内容最终为 blog_article。

上面介绍了 <sql> 节点的用法,比较容易。下面分析一下 sql 节点的解析过程,如下:

private void sqlElement(List<XNode> list) throws Exception { if (configuration.getDatabaseId() != null) { // 调用 sqlElement 解析 <sql> 节点 sqlElement(list, configuration.getDatabaseId()); } // 再次调用 sqlElement,不同的是,这次调用,该方法的第二个参数为 null sqlElement(list, null); }

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

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