mybatis 一對多

第一部分 示例

一、爲Teacher實體增加相關屬性

      爲教師實體增加指導學生集合的屬性如下:

  1. private List<Student> supStudents;//指導學生 

       併爲其增加setter和getter方法,這裏略過。

二、TeacherMapper接口

      爲實現教師實體映射,應先創建映射器接口如下:

  1. package com.abc.mapper;  
  2.  
  3. import com.abc.domain.Teacher;  
  4.  
  5. public interface TeacherMapper {  
  6.           
  7.     public Teacher getById(int id);  
  8.       
  9. }  

 三、映射文件

      爲教師實體創建的映射文件如下:

  1. <?xml version="1.0" encoding="utf8"?> 
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 
  3.      <!--與以前一樣,namespace的值是對應的映射器接口的完整名稱--> 
  4.      <mapper namespace="com.abc.mapper.TeacherMapper"> 
  5.         
  6.          <!--TeacherMapper接口中getById方法對應的SQL語句。  
  7.          查詢教師及其指導的學生的信息。由於教師、學生都有  
  8.          id、name、gender等屬性,因此給教師的字段都起了別名--> 
  9.          <select id="getById" parameterType="int"  resultMap="supervisorResultMap"> 
  10.           select t.id t_id, t.name t_name, t.gender t_gender,  
  11.           t.research_area t_research_area, t.title t_title,  
  12.           s.id,s.name, s.gender,s.major,s.grade  
  13.           from teacher t,student s where t.id=#{id}  
  14.           and s.supervisor_id = t.id  
  15.          </select> 
  16.  
  17.          <!--教師實體映射--> 
  18.          <resultMap id="supervisorResultMap" type="Teacher"> 
  19.             <id property="id" column="t_id"/> 
  20.             <result property="name" column="t_name"/> 
  21.             <result property="gender" column="t_gender"/> 
  22.             <result property="researchArea" column="t_research_area"/>   
  23.             <result property="title" column="t_title"/> 
  24.             <!--collection元素映射教師的指導學生集合的屬性。resultMap  
  25.             以命名空間名.resultMap的id的形式,引用studentResultMap。  
  26.             需要注意的是,上面的select語句中學生的字段名/別名應與  
  27.             studentResultMap中的column屬性一致--> 
  28.             <collection property="supStudents"   
  29.               resultMap="com.abc.mapper.StudentMapper.studentResultMap"/> 
  30.          </resultMap>      
  31.            
  32.    </mapper> 

       相應地,學生實體的映射文件如下:

  1. <?xml version="1.0" encoding="utf8"?> 
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 
  3.      <mapper namespace="com.abc.mapper.StudentMapper"> 
  4.         
  5.        <resultMap id="studentResultMap" type="Student"> 
  6.           <id property="id" column="id"/> 
  7.           <result property="name" column="name"/> 
  8.           <result property="gender" column="gender"/> 
  9.           <result property="major" column="major"/>   
  10.           <result property="grade" column="grade"/> 
  11.           <!--相應地,在此引用supervisorResultMap,亦採用  
  12.           命名空間名.resultMap的id的形式。--> 
  13.           <association property="supervisor"        
  14.           resultMap="com.abc.mapper.TeacherMapper.supervisorResultMap"/> 
  15.        </resultMap> 
  16.        
  17.      </mapper> 

       在工程的src\resources目錄下新建子目錄mappers,用來統一存放映射文件。爲了能讓MyBatis找到這些映射文件,修改其核心配置文件configuration.xml中的mappers元素如下:

  1. <!--在classpath中以相對路徑的形式引用映射文件--> 
  2. <mappers> 
  3.    <mapper resource="resources/mappers/StudentMapper.xml"/> 
  4. <mapper resource="resources/mappers/TeacherMapper.xml"/> 
  5. </mappers> 

       注意:resources目錄在工程編譯前會被複制到classes目錄下(詳見工程生成文件build.xml中的copy-resources和compile這兩個target),而classes目錄會被ant添加到classpath中。

四、執行類

      執行類爲CollectionDemo,其內容如下:

  1. package com.demo;  
  2.  
  3. import org.springframework.context.ApplicationContext;  
  4. import com.abc.mapper.StudentMapper;  
  5. import com.abc.mapper.TeacherMapper;  
  6. import com.abc.domain.Teacher;  
  7. import com.abc.domain.Student;  
  8. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  9. import java.util.List;  
  10.  
  11. public class CollectionDemo  
  12. {  
  13.     private static ApplicationContext ctx;  
  14.       
  15.     static 
  16.     {  
  17.         //在類路徑下尋找resources/beans.xml文件  
  18.         ctx = new ClassPathXmlApplicationContext("resources/beans.xml");  
  19.     }  
  20.       
  21.       
  22.     public static void main(String[] args)  
  23.     {  
  24.         //從Spring容器中請求映射器  
  25.         TeacherMapper mapper =   
  26.                (TeacherMapper)ctx.getBean("teacherMapper");  
  27.  
  28.         //查詢id爲1的教師  
  29.         Teacher teacher = mapper.getById(1);  
  30.  
  31.         if(teacher == null)  
  32.         {  
  33.             System.out.println("未找到相關教師信息。");  
  34.         }  
  35.         else 
  36.         {  
  37.             //教師信息  
  38.             System.out.println("**********************************************");  
  39.             System.out.println("教師姓名:" + "  " + teacher.getName());  
  40.             System.out.println("教師職稱:" + "  " + teacher.getTitle());  
  41.             System.out.println("**********************************************");  
  42.               
  43.             System.out.println("指導學生信息:");  
  44.             //遍歷指導的學生  
  45.             for(Student s : teacher.getSupStudents())  
  46.             {  
  47.                System.out.println("**********************************************");  
  48.                System.out.println( s.getName() + "  " + s.getGender() + "  " + s.getGrade()  
  49.                                 + "  " + s.getMajor());  
  50.                //從學生端訪問教師  
  51.                System.out.println("指導教師研究方向:" + s.getSupervisor().getResearchArea());  
  52.               
  53.             }  
  54.  
  55.             System.out.println("**********************************************");  
  56.         }         
  57.  
  58.     }  
  59.  

       從中可看出,可以從任意一端訪問另一端的對象。



第二部分 :上面是比較典型的使用方式,還有其他方式即:嵌套的Select,但是會產生 N+1的問題

(1)  association 中嵌套select

  1. <?xml version="1.0" encoding="utf8"?> 
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 
  3.      <mapper namespace="com.abc.mapper.StudentMapper"> 
  4.         
  5.      <select id="getById" parameterType="int"  resultMap="studentResultMap"> 
  6.           select id,name,gender,major,grade,supervisor_id from student where id=#{id}  
  7.      </select> 
  8.  
  9.      <select id="selectSupervisor" parameterType="int"  resultMap="supervisorResultMap"> 
  10.           select id,name,gender,title,research_area  
  11.           from teacher where id=#{id}  
  12.      </select> 
  13.  
  14.      <resultMap id="studentResultMap" type="Student"> 
  15.           <id property="id" column="id"/> 
  16.           <result property="name" column="name"/> 
  17.           <result property="gender" column="gender"/> 
  18.           <result property="major" column="major"/>   
  19.           <result property="grade" column="grade"/> 
  20.             
  21.           <!--column="supervisor_id"不能少。此列的值作爲參數  
  22.           傳遞給要引用的select語句,用來查詢相應學生的指導教師  
  23.           的信息。select屬性指定要引用的select語句--> 
  24.           <association property="supervisor" javaType="Teacher" 
  25.           column="supervisor_id" select="selectSupervisor"/> 
  26.      </resultMap> 
  27.        
  28.      <!--教師實體映射--> 
  29.      <resultMap id="supervisorResultMap" type="Teacher"> 
  30.          <id property="id" column="id"/> 
  31.          <result property="name" column="name"/> 
  32.          <result property="gender" column="gender"/> 
  33.          <result property="researchArea" column="research_area"/>   
  34.          <result property="title" column="title"/> 
  35.      </resultMap> 
  36.            
  37.    </mapper> 

(2)collection 中嵌套select

二、嵌套的select語句

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

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

  1. <?xml version="1.0" encoding="utf8"?> 
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 
  3.      <mapper namespace="com.abc.mapper.StudentMapper"> 
  4.         
  5.        <resultMap id="studentResultMap" type="Student"> 
  6.           <id property="id" column="id"/> 
  7.           <result property="name" column="name"/> 
  8.           <result property="gender" column="gender"/> 
  9.           <result property="major" column="major"/>   
  10.           <result property="grade" column="grade"/> 
  11.           <!--在這裏引用supervisorResultMap和getById,亦採用  
  12.           命名空間名.相關元素id的形式。column="supervisor_id" 
  13.           屬性不可少--> 
  14.           <association property="supervisor"        
  15.           resultMap="com.abc.mapper.TeacherMapper.supervisorResultMap" 
  16.           select="com.abc.mapper.TeacherMapper.getById" column="supervisor_id"/> 
  17.        </resultMap> 
  18.  
  19.        <!--根據指導教師id查詢學生信息--> 
  20.        <select id="getStudents" parameterType="int"   
  21.          resultMap="studentResultMap"> 
  22.             select * from student where supervisor_id = #{id}  
  23.        </select> 
  24.        
  25.      </mapper> 

  
第三部分 :延遲加載

1、MyBatis的延遲加載機制需要使用cglib包,因此應向工程中添加此包,本文使用的是cglib-nodep-2.2.3.jar。

      2、在MyBatis的核心配置文件(在本示例中是configuration.xml)裏的settings元素中添加以下配置:

  1. <setting name="lazyLoadingEnabled" value="true" /> 
  2. <setting name="aggressiveLazyLoading" value="false" /> 

      現在來對延遲加載進行測試。首先改造類CollectionDemo.java,讓它先遍歷查找到的教師,然後遍歷某個教師指導的學生的信息

  1. //分頁查詢教師信息  
  2. List<Teacher> teachers =        mapper.findTeacherByPage(params);  
  3.  
  4. if(teachers == null)  
  5.   {  
  6.      System.out.println("未找到相關教師信息。");  
  7.   }  
  8. else 
  9.   {           
  10.      Object[] t = teachers.toArray();  
  11.      System.out.println("**********************************************");  
  12.  
  13.       for(int i = 0; i < t.length; i++)  
  14.     {  
  15.        teacher = (Teacher)t[i];  
  16.        System.out.println("教師姓名:" + "  " + teacher.getName());  
  17.             System.out.println("教師職稱:" + "  " + teacher.getTitle());  
  18.        System.out.println("**********************************************");  
  19.     }  
  20.  
  21.    //遍歷當前teacher對象指導的學生  
  22.    for(Student s : teacher.getSupStudents())  
  23.    {  
  24.      System.out.println( s.getName() + "  " +  s.getGender  () + "  " + s.getGrade()  
  25.            + "  " + s.getMajor());  
  26.    }  
  27. }    

     原文 http://legend2011.blog.51cto.com/3018495/973579


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章