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