我的技術博客經常被流氓網站惡意爬取轉載。請移步原文:http://www.cnblogs.com/hamhog/p/3959451.html,享受整齊的排版、有效的鏈接、正確的代碼縮進、更好的閱讀體驗。
背景
我們知道,MyBatis可以很方便地把SQL select出來的數據直接映射為對象的屬性,把對象取出來。
但是,有些對象的屬性是集合類型,集合里保存的是數個其他類型的對象。如何用MyBatis把它取出來呢?
例子
以以下這個應用場景為例:一個教師對應多個課程。
數據結構如下:
public class Course{ int id; String name; } public class Tutor{ int id; String name; List<Course> courses; }
這時,就需要分別寫出兩者的ResultMap:
<resultMap type="Course" id="courseResult"> <result column="course_id" property="id" /> <result column="course_name" property="name" /> </resultMap> <resultMap type="Tutor" id="tutorResult"> <id column="tutor_id" property="id" /> <result column="tutor_name" property="name" /> <collection property="courses" resultMap="Course" /> </resultMap>
然后把select語句的resultMap設為tutorResult:
<select id="findTutorById" parameterType="int" resultMap="TutorResult"> SELECT TUTOR_ID, TUTOR_NAME, COURSE_ID, COURSE_NAME FROM TUTOR </select>
這樣就能把Tutor類的數據正確地讀進來了。
實驗
以上這個例子來自《Java Persistence with MyBatis3》。讓我好奇的是,myBatis是如何判斷,哪些course應該對應同一個tutor的呢?對於每個course,它是怎么尋找應該把它放進哪個tutor的List里呢?
用以上的例子,數據為:
tutor_id | tutor_name | course_id | course_name |
1 | 張三 | 1 | 語文 |
2 | 李四 | 2 | 數學 |
讀進來的數據是,大概是這樣的:
張三 : 語文
李四 : 數學
如果我們把數據改成這樣:
tutor_id | tutor_name | course_id | course_name |
1 | 張三 | 1 | 語文 |
1 | 李四 | 2 | 數學 |
讀進來的數據,就會變成這樣:
張三:語文, 數學
“李四”沒有了。數學歸進了張三里。這是為什么呢?
原來,Tutor的ResultMap里,指定了id為tutor_id。一旦指定了id,myBatis就認定它是全局唯一的;李四的id與張三相同,因此會被認為是同一個對象,則李四的數據被直接忽略。
上面這個例子可以說明,如果有指定id,會去根據id判斷是否為同一個對象。id相同,即使屬性不同,還是認為是同一個對象。
而我們如果把id改為普通的result,把Tutor的ResultMap改成這樣:
<resultMap type="Tutor" id="tutorResult"> <result column="tutor_id" property="id" /> <result column="tutor_name" property="name" /> <collection property="courses" resultMap="Course" /> </resultMap>
此時,仍然用剛才的數據:
tutor_id | tutor_name | course_id | course_name |
1 | 張三 | 1 | 語文 |
1 | 李四 | 2 | 數學 |
則讀進來的數據,就會變成這樣了:
張三:語文
李四:數學
上面這個例子可以說明,如果沒有指定id,會去根據所有屬性去判斷是否為同一個對象。只要有一個屬性不同,就認為不是同一個對象。
如果把數據改為:
tutor_id | tutor_name | course_id | course_name |
1 | 張三 | 1 | 語文 |
1 | 張三 | 2 | 數學 |
則讀進來的數據,就會變成:
張三:語文,數學
如果所有屬性都相同,就會認為是同一個對象了。
寫到這里,發現思路不太清晰。其實course按照什么去找tutor,主要看的是同一行的tutor,看是這個tutor是不是新的。