mybatis映射系列教程6:集合映射
一个博客(Blog)只有一个作者(Author),但一个博客有很多文章(Post)。 在博客类中,这可以用下面的写法来表示:
private List<Post> posts;
映射结果集合到一个 List 中,可以使用集合元素<collection>。和关联映射一样,我们可以使用嵌套 Select 查询,或基于连接的嵌套结果映射集合。
1、集合的嵌套 Select 查询
首先,让我们看看如何使用嵌套 Select 查询来为博客加载文章。
<resultMap id="blogResult" type="Blog">
<collection property="posts" javaType="ArrayList" column="id" ofType="Post" select="selectPostsForBlog"/>
</resultMap>
<select id="selectBlog" resultMap="blogResult">
SELECT * FROM BLOG WHERE ID = #{id}
</select>
<select id="selectPostsForBlog" resultType="Post">
SELECT * FROM POST WHERE BLOG_ID = #{id}
</select>
此时出现一个新的 "ofType" 属性。这个属性非常重要,它用来将 JavaBean(或字段)属性的类型和集合存储的类型区分开来。所以你可以按照下面这样来阅读映射:
<collection property="posts" javaType="ArrayList" column="id" ofType="Post" select="selectPostsForBlog"/>
读作: posts 是一个存储 Post 的 ArrayList 集合
在一般情况下,MyBatis 可以推断 javaType 属性,因此并不需要填写。所以很多时候你可以简略成:
<collection property="posts" column="id" ofType="Post" select="selectPostsForBlog"/>
2、集合的嵌套结果映射
首先,让我们看看对应的 SQL 语句:
<select id="selectBlog" resultMap="blogResult">
select
B.id as blog_id,
B.title as blog_title,
B.author_id as blog_author_id,
P.id as post_id,
P.subject as post_subject,
P.body as post_body,
from Blog B
left outer join Post P on B.id = P.blog_id
where B.id = #{id}
</select>
我们再次连接了博客表和文章表,并且为每一列都赋予了一个有意义的别名,以便映射保持简单。要映射博客里面的文章集合,就这么简单:
<resultMap id="blogResult" type="Blog">
<id property="id" column="blog_id" />
<result property="title" column="blog_title"/>
<collection property="posts" ofType="Post">
<id property="id" column="post_id"/>
<result property="subject" column="post_subject"/>
<result property="body" column="post_body"/>
</collection>
</resultMap>
如果你喜欢更详略的、可重用的结果映射,你可以使用下面的等价形式:
<resultMap id="blogResult" type="Blog">
<id property="id" column="blog_id" />
<result property="title" column="blog_title"/>
<collection property="posts" ofType="Post" resultMap="blogPostResult" columnPrefix="post_"/>
</resultMap>
<resultMap id="blogPostResult" type="Post">
<id property="id" column="id"/>
<result property="subject" column="subject"/>
<result property="body" column="body"/>
</resultMap>
备注:Mybatis中 collection 和 association 的区别?
public class Blog
{
private Author author;
private List<Post> posts;
}
当映射author属性时用association标签,这是一对一的关系;当映射posts时用collection标签,这是一对多的关系