mybatis resultMap标签注意事项(pageHelper结合使用的坑)
背景
使用pageHelper时,发现分页数据异常,经过排查发现是resultMap 的问题。
resultMap介绍
在使用mybatis时,我们经常会使用在xml文件中编写一些复杂的sql语句,例如多表的join,在映射实体类时,又会使用到resultMap,将查询的数据库字段与实体类字段进行映射对照。
resultMap 元素是 MyBatis 中最重要最强大的元素。它可以让你从 90% 的 JDBC ResultSets 数据提取代码中解放出来,并在一些情形下允许你进行一些 JDBC 不支持的操作。实际上,在为一些比如连接的复杂语句编写映射代码的时候,一份 resultMap 能够代替实现同等功能的数千行代码。ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了。
举例
当我们编写了一个非常复杂的resultMap时,例如如下。
<!-- 非常复杂的结果映射 -->
<resultMap id="detailedBlogResultMap" type="Blog"><constructor><idArg column="blog_id" javaType="int"/></constructor><result property="title" column="blog_title"/><association property="author" javaType="Author"><id property="id" column="author_id"/><result property="username" column="author_username"/><result property="password" column="author_password"/><result property="email" column="author_email"/><result property="bio" column="author_bio"/><result property="favouriteSection" column="author_favourite_section"/></association><collection property="posts" ofType="Post"><id property="id" column="post_id"/><result property="subject" column="post_subject"/><association property="author" javaType="Author"/><collection property="comments" ofType="Comment"><id property="id" column="comment_id"/></collection><collection property="tags" ofType="Tag" ><id property="id" column="tag_id"/></collection><discriminator javaType="int" column="draft"><case value="1" resultType="DraftPost"/></discriminator></collection>
</resultMap>
请把你的目光聚集到collection标签上,对应Java 实体类属性为List posts;
有两张表 blog 和 post, 一对多的关系。
一个blog 博客,可以用多篇post文章。
我们查询博客以及文章,并且装配到统一个实体类中。
select blog.*,post.title,post.status from blog left join post using(post_id);
假设查询到5条数据,两个博客,分别对应的1、4篇文章。那么被resultMap映射过会得到一个拥有两个元素的集合,文章数据被封装到对应的集合属性中。
但是如果我们在sql最后加入 limi 2, 这样查到的分页数据就是不准确的了。
查出来还是两个元素的集合,但是第二个元素的posts 属性却只有一篇文章,和我们预期严重不符合
会出现各种情况,posts属性数据不完整,或者是其他数据不正确的情况。
结论
所以当我们需要使用resultMap + collection来进行复杂映射时,慎重使用 limit 关键字,以及一些插件(pageHelper)