MyBatis多对多关联查询示例——MyBatis学习笔记之十八
MyBatis系列的上一篇博客發表時,笑笑還沒有出生。轉眼間八個月過去了,他已經是個大寶寶了。這么長時間未更新MyBatis系列的博客,想來真是罪過。不過有了寶寶之后,的確會分散自己很大一部分精力。
今天的示例是多對多關聯的查詢,這是在上一篇博客(MyBatis多對多保存示例)的基礎上完成的,仍然是處理學生與課程之間的多對多關聯(一個學生可以選修多門課程,一門課程可以被多個學生選修),相關的實體類和表結構信息請參考上篇博客。
從本篇博客起,示例工程就不再用ant組織,而改用eclipse(示例工程源碼及數據庫腳本下載地址:http://down.51cto.com/data/1143560)。
首先實現學生端功能,即根據id查詢出學生及其選修的課程。步驟如下:
1、在StudentMapper.xml中編寫id為“studentResultMap”的resultMap元素,如下:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <!-- 查詢學生的結果映射,只映射簡單屬性 --> <resultMap?id="simpleStudent"?type="Student"> <id?property="id"?column="s_id"?/> <result?property="name"?column="s_name"?/> <result?property="gender"?column="s_gender"?/> <result?property="major"?column="s_major"?/> <result?property="grade"?column="s_grade"?/> </resultMap> <!-- 查詢學生的結果映射,含指導教師、選修課程等復雜屬性的映射,從simpleStudent繼承而來,提高resultMap的靈活性和重用性 --> <resultMap?id="studentResultMap"?type="Student"?extends="simpleStudent"> <!--association的嵌套的結果映射方式。 --> <association?property="supervisor"?javaType="Teacher"?resultMap="com.abc.mapper.TeacherMapper.simpleTeacher"> </association> <!-- 嵌入的select查詢方式,查詢學生選修的課程。采用了CourseMapper.xml文件中的id為getByStudentId的select元素,這里的com.abc.mapper.CourseMapper是其命名空間名 --> <collection?property="courses"?ofType="Course"?select="com.abc.mapper.CourseMapper.getByStudentId"?column="s_id"> </collection> </resultMap> |
這里的關鍵點在于,為了查詢學生選修的課程,用到了collection元素,其查詢方式是嵌套的select方式。其select語句采用了CourseMapper.xml文件中的id為getByStudentId的select元素,這里的com.abc.mapper.CourseMapper是其命名空間名(關于collection元素的嵌套select語句的方式,請參考本系列的博文:MyBatis?collection的兩種形式)。注意這里用到了resultMap元素的繼承,提高resultMap元素的靈活性和重用性。
2、在CourseMapper.xml文件中相應的select元素及結果映射如下所示:
| 1 2 3 4 5 6 7 8 9 10 11 | <!--課程實體映射--> <resultMap?id="simpleCourse"?type="Course"> <id?property="id"?column="course_id"/> <result?property="courseCode"?column="course_code"/> <result?property="courseName"?column="course_name"/> </resultMap> <select?id="getByStudentId"?parameterType="int" resultMap="simpleCourse"> select c.id course_id,course_code,course_name from course c,student_course sc where sc.student_id=#{id} and sc.course_id = c.id </select> |
測試類如下:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | package?com.demo; import?java.util.List; import?org.springframework.context.ApplicationContext; import?com.abc.service.CourseService; import?com.abc.service.StudentService; import?com.abc.domain.Course; import?com.abc.domain.Student; import?com.abc.domain.Teacher; import?org.springframework.context.support.ClassPathXmlApplicationContext; public?class?ManyToManyQuery { private?static?ApplicationContext ctx; static { //在類路徑下尋找spring主配置文件,啟動spring容器 ctx =?new?ClassPathXmlApplicationContext("classpath:applicationContext.xml"); } public?static?void?main(String[] args) { int?i =?0, length =?0; List<Course> list =?null; StudentService studentService = (StudentService)ctx.getBean("studentService"); Student student = studentService.getById(7); //獲取該學生選修的課程 list = student.getCourses(); StringBuilder info =?new?StringBuilder("學生姓名:"); info.append(student.getName()); info.append("??? "); length = list.size(); while(i < length) { info.append("所選課程名稱:"); info.append(list.get(i).getCourseName()); info.append("??? "); i++; } System.out.println(info.toString()); } } |
注意,與前面的工程相比,本工程的文件布局和名稱都有一些變化,新增了com.abc.service包,用到了更多的Spring的相關知識。具體內容請參看作者的公開課:http://bbs.51cto.com/open/do/course/cid/65。
運行結果如下:
現在實現課程端功能,即根據id查詢出課程及選修這門課程的學生。步驟如下:
1、在CourseMapper.java中聲明方法getById,即根據id查詢課程。代碼如下:
| 1 | public?Course getById(int?id); |
2、在CourseMapper.xml中編寫對應的select語句,如下:
| 1 2 3 4 5 6 7 | <!--根據id查詢課程及選修的學生--> <select?id="getById"?parameterType="int"???resultMap="courseResutMap"> select c.id course_id,c.course_code course_code,c.course_name course_name, s.id s_id, s.name s_name, s.gender s_gender, s.grade s_grade, s.major s_major from course c left join student_course sc on c.id = sc.course_id left join student s on sc.student_id = s.id where c.id = #{id} </select> |
3、此select語句用到了id為courseResutMap的resultMap元素,如下:
| 1 2 3 4 5 6 7 8 9 10 | <!--課程實體映射,映射簡單屬性--> <resultMap?id="simpleCourse"?type="Course"> <id?property="id"?column="course_id"/> <result?property="courseCode"?column="course_code"/> <result?property="courseName"?column="course_name"/> </resultMap> <!--課程實體映射,除映射簡單屬性,還包含students復雜屬性映射--> <resultMap?id="courseResutMap"?type="Course"?extends="simpleCourse"> <collection?property="students"?resultMap="com.abc.mapper.StudentMapper.simpleStudent"/> </resultMap> |
這里的關鍵點還是用到了collection元素,只是這次用到了嵌套的resultMap形式(關于collection元素的嵌套的resultMap形式,請參考本系列的博文:MyBatis?collection的兩種形式),而且在這里也同樣用到了resultMap元素的繼承。simpleStudent是StudentMapper.xml文件中的resultMap元素,com.abc.mapper.StudentMapper是其命名空間名。
請注意,id為“simpleStudent”和“simpleCourse”的兩個resultMap元素都得到了重用。其中,StudentMapper.xml和CourseMapper.xml中各引用了simpleStudent一次,CourseMapper.xml中引用了simpleCourse兩次。
測試類如下:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | package?com.demo; import?java.util.List; import?org.springframework.context.ApplicationContext; import?com.abc.service.CourseService; import?com.abc.service.StudentService; import?com.abc.domain.Course; import?com.abc.domain.Student; import?com.abc.domain.Teacher; import?org.springframework.context.support.ClassPathXmlApplicationContext; public?class?ManyToManyQuery { private?static?ApplicationContext ctx; static { //在類路徑下尋找spring主配置文件,啟動spring容器 ctx =?new?ClassPathXmlApplicationContext("classpath:applicationContext.xml"); } public?static?void?main(String[] args) { int?i =?0, length =?0; List<Student> list =?null; CourseService courseService = (CourseService)ctx.getBean("courseService"); Course course = courseService.getById(1); //獲取選修了此課程的學生 list = course.getStudents(); length = list.size(); StringBuilder info =?new?StringBuilder("課程名稱:"); info.append(course.getCourseName()); info.append("?? 選修此課程的學生姓名:"); while(i < length) { info.append(list.get(i).getName()); info.append("?? "); i++; } System.out.println(info.toString()); } } |
執行結果如下:
本文轉自 NashMaster2011 51CTO博客,原文鏈接:http://blog.51cto.com/legend2011/1401407,如需轉載請自行聯系原作者 與50位技術專家面對面20年技術見證,附贈技術全景圖
總結
以上是生活随笔為你收集整理的MyBatis多对多关联查询示例——MyBatis学习笔记之十八的全部內容,希望文章能夠幫你解決所遇到的問題。