示例:html
<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
其餘全部的屬性將會被自動加載,假設它們的列和屬性名相匹配。sql
這種方式很簡單, 可是對於大型數據集合和列表將不會表現很好。 問題就是咱們熟知的 「N+1 查詢問題」。歸納地講,N+1 查詢問題能夠是這樣引發的:mybatis
這個問題會致使成百上千的 SQL 語句被執行。這一般不是指望的。性能
MyBatis 能延遲加載這樣的查詢就是一個好處,所以你能夠分散這些語句同時運行的消 耗。然而,若是你加載一個列表,以後迅速迭代來訪問嵌套的數據,你會調用全部的延遲加 載,這樣的行爲多是很糟糕的。spa
因此還有另一種方法。xml
在上面你已經看到了一個很是複雜的嵌套關聯的示例。 下面這個是一個很是簡單的示例 來講明它如何工做。代替了執行一個分離的語句,咱們聯合博客表和做者表在一塊兒,就像:htm
<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.password as author_password, A.email as author_email, A.bio as author_bio from Blog B left outer join Author A on B.author_id = A.id where B.id = #{id} </select>
注意這個聯合查詢, 以及採起保護來確保全部結果被惟一併且清晰的名字來重命名。 這使得映射很是簡單。如今咱們能夠映射這個結果:blog
<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"/> </resultMap> <resultMap id="authorResult" type="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"/> </resultMap>
在上面的示例中你能夠看到博客的做者關聯表明着「authorResult」結果映射來加載做 者實例。ci
很是重要: id元素在嵌套結果映射中扮演着非 常重要的角色。你應該老是指定一個或多個能夠惟一標識結果的屬性。實際上若是你不指定它的話, MyBatis仍然能夠工做,可是會有嚴重的性能問題。在能夠惟一標識結果的狀況下, 儘量少的選擇屬性。主鍵是一個顯而易見的選擇(即便是複合主鍵)。
如今,上面的示例用了外部的結果映射元素來映射關聯。這使得 Author 結果映射能夠 重用。然而,若是你不須要重用它的話,或者你僅僅引用你全部的結果映射合到一個單獨描 述的結果映射中。你能夠嵌套結果映射。這裏給出使用這種方式的相同示例:
<resultMap id="blogResult" type="Blog"> <id property="id" column="blog_id" /> <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"/> </association> </resultMap>
若是blog有一個co-author怎麼辦? select語句將看起來這個樣子:
<select id="selectBlog" resultMap="blogResult"> select B.id as blog_id, B.title as blog_title, A.id as author_id, A.username as author_username, A.password as author_password, A.email as author_email, A.bio as author_bio, CA.id as co_author_id, CA.username as co_author_username, CA.password as co_author_password, CA.email as co_author_email, CA.bio as co_author_bio from Blog B left outer join Author A on B.author_id = A.id left outer join Author CA on B.co_author_id = CA.id where B.id = #{id} </select>
再次調用Author的resultMap將定義以下:
<resultMap id="authorResult" type="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"/> </resultMap>
由於結果中的列名與resultMap中的列名不一樣。 你須要指定columnPrefix去重用映射co-author結果的resultMap。
<resultMap id="blogResult" type="Blog"> <id property="id" column="blog_id" /> <result property="title" column="blog_title"/> <association property="author" resultMap="authorResult" /> <association property="coAuthor" resultMap="authorResult" columnPrefix="co_" /> </resultMap>
上面你已經看到了如何處理「有一個」類型關聯。可是「有不少個」是怎樣的?下面這 個部分就是來討論這個主題的。
官方連接:http://www.mybatis.org/mybatis-3/zh/sqlmap-xml.html