集合(collection)

<collection property="posts" ofType="domain.blog.Post">
  <id property="id" column="post_id"/>
  <result property="subject" column="post_subject"/>
  <result property="body" column="post_body"/>
</collection>

集合的嵌套 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属性的类型(javaType)和集合存储的类型区分开来。在一般情况下,MyBatis 可以推断 javaType 属性,因此并不需要填写。

集合的嵌套结果映射

集合的嵌套结果映射除了新增的 “ofType” 属性,它和关联(association)的完全相同。

<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>

注意:

MyBatis在处理结果的时候,会判断结果是否相同,如果是相同的结果,则只会保留第一个结果。

MyBatis判断结果是否相同时,最简单的情况就是在映射配置中至少有一个id标签。因为MyBatis的resultMap只用于配置结果如何映射,并不知道这个表具体如何。id的唯一作用就是在嵌套的映射配置时判断数据是否相同,当配置id标签时,MyBatis只需要逐条比较所有数据中id标签配置的字段值是否相同即可。在配置嵌套结果查询时,配置id标签可以提高处理效率。

没有配置id时,MyBatis就会把resultMap中配置的所有字段进行比较,如果所有字段的值都相同就合并,只要有一个字段值不同,就不合并。

在嵌套结果配置id属性时,如果查询语句中没有查询id属性配置的列,就会导致id对应的值为null。这种情况下,所有值的id都相同,因此会使嵌套的集合中只有一条数据。所以在配置id列时,查询语句中必须包含该列。

Last updated