<association property="author" column="blog_author_id" javaType="Author"> <id property="id" column="author_id"/> <result property="username" column="author_username"/> </association>
<resultMap id="blogResult" type="Blog"> <association property="author" column="author_id" javaType="Author" select="selectAuthor"/> </resultMap> <select id="selectBlog" resultMap="blogResult"> SELECT * FROM BLOG WHERE ID = #{id} </select> <select id="selectAuthor" resultType="Author"> SELECT * FROM AUTHOR WHERE ID = #{id} </select>
上述有两个查询语句:一个来加载博客,另一个来加载做者,并且博客的结果映射描述了“selectAuthor”语句应该被用来加载它的author属性值。java
这种方式很简单,可是对于大型数据集合和列表将不会表现很好。问题就是咱们所熟知的“N+1”查询问题:dom
这个问题会致使成百上千的SQL语句被执行,不是所指望的。post
<resultMap id="blogResult" type="Blog"> <id property="id" column="blog_id" jdbcType="BIGINT" /> <result property="title" column="blog_title" jdbcType="VARCHAR" /> <association property="author" column="blog_author_id" javaType="Author" resultMap="authorResult" /> </resultMap> <resultMap id="authorResult" type="Author"> <id property="id" column="author_id" jdbcType="BIGINT" /> <result property="username" column="author_username" jdbcType="VARCHAR" /> <result property="email" column="author_email" jdbcType="VARCHAR" /> <result property="bio" column="author_bio" jdbcType="VARCHAR" /> </resultMap> <select id="selectBlog" resultMap="blogResult"> select b.id as blog_id, b.title as blog_title, b.author_id as blog_author_id, a.id as author_id, a.username as author_username, a.email as author_email, a.bio as author_bio from Blog B left outer join Author a on a.id = B.author_id where B.id = #{id} </select>
上面的示例中,博客的做者关联表明着“authorResult”结果映射来加载做者实例。性能
很是重要: id元素在嵌套结果映射中扮演着很是重要的角色。你应该老是指定一个或多个能够惟一标识结果的属性。实际上若是不指定它的话,MyBatis仍然能够工做,可是会有严重的性能问题。code
上面的示例中,使用了外部的结果嵌套来映射关联。这使得Author结果映射能够重用。然而,若是不须要重用它的话,你能够嵌套结果映射。以下示例:blog
<resultMap id="blogResult" type="Blog"> <id property="id" column="blog_id" jdbcType="BIGINT" /> <result property="title" column="blog_title" jdbcType="VARCHAR" /> <association property="author" javaType="Author" jdbcType="BIGINT"> <id property="id" column="author_id" /> <result property="username" column="author_username" jdbcType="VARCHAR" /> <result property="email" column="author_email" jdbcType="VARCHAR" /> <result property="bio" column="author_bio" jdbcType="VARCHAR" /> </assoaction> </resultMap>
上面是如何处理“有一个”类型关联。可是对于“有多个”,需借助集合来关联。ci
<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>
集合元素的做用几乎和关联是相同的。继续上面的示例,一个博客只有一个做者。可是博客有不少文章。在JavaBean的博客Blog类中,能够用下面的示例来表述:博客
private List<Post> posts;
<resultMap id="blogResult" type="Blog"> <id property="id" column="blog_id" /> <result property="title" column="blog_title" /> <association property="author" column="blog_author_id" javaType="Author" resultMap="authorResult" /> <collection property="posts" column="id" javaType="ArrayList" ofType="Post" select="selectPosts4Blog" /> </resultMap> <select id="selectBlog" resultMap="blogResult"> select * from blog where id=#{id} </select> <select id="selectPosts4Blog" resultType="Post"> select * from post where blog_id = #{id} </select>
注意:ofType属性,用来区分JavaBean属性类型和集合包含的类型。it
<collection property="posts" javaType="ArrayList" column="id" ofType="Post" select="selectPosts4Blog" />
javaType属性不是必需的,由于MyBatis在不少状况下会自动计算出来。io
<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> <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 join post p on p.blog_id = b.id where id = #{id} </select>