MyBatis collection的兩種形式——MyBatis學習筆記之九


 與association一樣,collection元素也有兩種形式,現介紹如下:

一、嵌套的resultMap

      實際上以前的示例使用的就是這種方法,今天介紹它的另一種寫法。還是以教師映射為例,修改映射文件TeacherMapper.xml如下(點擊此處進入嵌套resultMap形式的示例源碼下載頁面。注:本示例代碼是在修改本系列的上篇博文示例代碼的基礎上完成的,用到了MapperScannerConfigurer和注解等知識。對這些知識不熟悉的讀者,可參考上篇博文:http://legend2011.blog.51cto.com/3018495/980150):

<?xml version="1.0" encoding="utf8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--與以前一樣,namespace的值是對應的映射器接口的完整名稱-->
<mapper namespace="com.abc.mapper.TeacherMapper">
<!--TeacherMapper接口中getById方法對應的SQL語句。
查詢教師及其指導的學生的信息。由於教師、學生都有
id、name、gender等屬性,因此給教師的字段都起了別名-->
<select id="getById" parameterType="int" resultMap="supervisorResultMap">
select t.id t_id, t.name t_name, t.gender t_gender,
t.research_area t_research_area, t.title t_title,
s.id,s.name, s.gender,s.major,s.grade
from teacher t,student s where t.id=#{id}
and s.supervisor_id = t.id
</select>
<!--教師實體映射-->
<resultMap id="supervisorResultMap" type="Teacher">
<id property="id" column="t_id"/>
<result property="name" column="t_name"/>
<result property="gender" column="t_gender"/>
<result property="researchArea" column="t_research_area"/>
<result property="title" column="t_title"/>
<!--需要注意的是,上面的select語句中學生的字段名/別名應與
下面的column屬性一致。ofType指collection包含的元素的類型,
此屬性不可少-->
<collection property="supStudents"ofType="Student">
<id property="id" column="id"/>
<result property="name"   column="name"/>
<result property="gender" column="gender"/>
<result property="major"  column="major"/>
<result property="grade"  column="grade"/>
<!--映射學生的指導教師屬性,用到了
supervisorResultMap本身-->
<association property="supervisor"
resultMap="supervisorResultMap"/>
</collection>
</resultMap>
</mapper>

    運行程序結果如下: 

       與以前的寫法相比,這種寫法的缺點是學生實體映射被嵌入到教師實體映射中,因此學生實體映射不能被重用。

二、嵌套的select語句

      這種方式是使用一條單獨的select語句來加載關聯的實體(在本例中就是學生實體),然后在collection元素中引用此select語句(注:此方法會產生N+1問題,關於這個問題可參考本系列博客中的“MyBatis中的N+1問題”)。首先修改TeacherMapper.xml如下(點擊此處進入嵌套select語句形式示例源碼下載頁面):

<?xml version="1.0" encoding="utf8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--與以前一樣,namespace的值是對應的映射器接口的完整名稱-->
<mapper namespace="com.abc.mapper.TeacherMapper">
<!--TeacherMapper接口中getById方法對應的SQL語句。
查詢教師的信息。-->
<select id="getById" parameterType="int" resultMap="supervisorResultMap">
select * from teacher where id=#{id}
</select>
<!--教師實體映射-->
<resultMap id="supervisorResultMap" type="Teacher">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="gender" column="gender"/>
<result property="researchArea" column="research_area"/>
<result property="title" column="title"/>
<!--ofType指collection包含的元素的類型,此屬性不可少。
column屬性指把上述的getById的select語句中的教師id列的值作為參數
傳遞給將要引用到的下述的getStudents的select語句,此屬性不可少。
引用的形式為:命名空間.select語句id-->
<collection property="supStudents" column="id" ofType="Student"
select="com.abc.mapper.StudentMapper.getStudents"/>
</resultMap>
</mapper>

 

     在這里把根據指導教師id查詢學生信息的SQL語句寫在StudentMapper.xml中,並引用其中的學生實體映射studentResultMap。修改StudentMapper.xml如下:

<?xml version="1.0" encoding="utf8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.abc.mapper.StudentMapper">
<resultMap id="studentResultMap" type="Student">
<id property="id" column="id"/>
<result property="name"   column="name"/>
<result property="gender" column="gender"/>
<result property="major"  column="major"/>
<result property="grade"  column="grade"/>
<!--在這里引用supervisorResultMap和getById,
亦采用命名空間名.相關元素id的形式。
column="supervisor_id"屬性不可少-->
<association property="supervisor"
resultMap="com.abc.mapper.TeacherMapper.supervisorResultMap"
select="com.abc.mapper.TeacherMapper.getById"
column="supervisor_id"/>
</resultMap>
<!--根據指導教師id查詢學生信息-->
<select id="getStudents" parameterType="int"
resultMap="studentResultMap">
select * from student where supervisor_id = #{id}
</select>
</mapper>

 

 執行結果如下:

      從以上可看出,collection的這兩種形式與association的兩種形式非常相似。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM