MyBatis多对多关联查询示例——MyBatis学习笔记之十八
MyBatis系列的上一篇博客發(fā)表時(shí),笑笑還沒(méi)有出生。轉(zhuǎn)眼間八個(gè)月過(guò)去了,他已經(jīng)是個(gè)大寶寶了。這么長(zhǎng)時(shí)間未更新MyBatis系列的博客,想來(lái)真是罪過(guò)。不過(guò)有了寶寶之后,的確會(huì)分散自己很大一部分精力。
今天的示例是多對(duì)多關(guān)聯(lián)的查詢,這是在上一篇博客(MyBatis多對(duì)多保存示例)的基礎(chǔ)上完成的,仍然是處理學(xué)生與課程之間的多對(duì)多關(guān)聯(lián)(一個(gè)學(xué)生可以選修多門課程,一門課程可以被多個(gè)學(xué)生選修),相關(guān)的實(shí)體類和表結(jié)構(gòu)信息請(qǐng)參考上篇博客。
從本篇博客起,示例工程就不再用ant組織,而改用eclipse(示例工程源碼及數(shù)據(jù)庫(kù)腳本下載地址:http://down.51cto.com/data/1143560)。
首先實(shí)現(xiàn)學(xué)生端功能,即根據(jù)id查詢出學(xué)生及其選修的課程。步驟如下:
1、在StudentMapper.xml中編寫id為“studentResultMap”的resultMap元素,如下:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <!-- 查詢學(xué)生的結(jié)果映射,只映射簡(jiǎn)單屬性 --> <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> <!-- 查詢學(xué)生的結(jié)果映射,含指導(dǎo)教師、選修課程等復(fù)雜屬性的映射,從simpleStudent繼承而來(lái),提高resultMap的靈活性和重用性 --> <resultMap?id="studentResultMap"?type="Student"?extends="simpleStudent"> <!--association的嵌套的結(jié)果映射方式。 --> <association?property="supervisor"?javaType="Teacher"?resultMap="com.abc.mapper.TeacherMapper.simpleTeacher"> </association> <!-- 嵌入的select查詢方式,查詢學(xué)生選修的課程。采用了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> |
這里的關(guān)鍵點(diǎn)在于,為了查詢學(xué)生選修的課程,用到了collection元素,其查詢方式是嵌套的select方式。其select語(yǔ)句采用了CourseMapper.xml文件中的id為getByStudentId的select元素,這里的com.abc.mapper.CourseMapper是其命名空間名(關(guān)于collection元素的嵌套select語(yǔ)句的方式,請(qǐng)參考本系列的博文:MyBatis?collection的兩種形式)。注意這里用到了resultMap元素的繼承,提高resultMap元素的靈活性和重用性。
2、在CourseMapper.xml文件中相應(yīng)的select元素及結(jié)果映射如下所示:
| 1 2 3 4 5 6 7 8 9 10 11 | <!--課程實(shí)體映射--> <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> |
測(cè)試類如下:
| 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主配置文件,啟動(dòng)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); //獲取該學(xué)生選修的課程 list = student.getCourses(); StringBuilder info =?new?StringBuilder("學(xué)生姓名:"); 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的相關(guān)知識(shí)。具體內(nèi)容請(qǐng)參看作者的公開課:http://bbs.51cto.com/open/do/course/cid/65。
運(yùn)行結(jié)果如下:
現(xiàn)在實(shí)現(xiàn)課程端功能,即根據(jù)id查詢出課程及選修這門課程的學(xué)生。步驟如下:
1、在CourseMapper.java中聲明方法getById,即根據(jù)id查詢課程。代碼如下:
| 1 | public?Course getById(int?id); |
2、在CourseMapper.xml中編寫對(duì)應(yīng)的select語(yǔ)句,如下:
| 1 2 3 4 5 6 7 | <!--根據(jù)id查詢課程及選修的學(xué)生--> <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語(yǔ)句用到了id為courseResutMap的resultMap元素,如下:
| 1 2 3 4 5 6 7 8 9 10 | <!--課程實(shí)體映射,映射簡(jiǎn)單屬性--> <resultMap?id="simpleCourse"?type="Course"> <id?property="id"?column="course_id"/> <result?property="courseCode"?column="course_code"/> <result?property="courseName"?column="course_name"/> </resultMap> <!--課程實(shí)體映射,除映射簡(jiǎn)單屬性,還包含students復(fù)雜屬性映射--> <resultMap?id="courseResutMap"?type="Course"?extends="simpleCourse"> <collection?property="students"?resultMap="com.abc.mapper.StudentMapper.simpleStudent"/> </resultMap> |
這里的關(guān)鍵點(diǎn)還是用到了collection元素,只是這次用到了嵌套的resultMap形式(關(guān)于collection元素的嵌套的resultMap形式,請(qǐng)參考本系列的博文:MyBatis?collection的兩種形式),而且在這里也同樣用到了resultMap元素的繼承。simpleStudent是StudentMapper.xml文件中的resultMap元素,com.abc.mapper.StudentMapper是其命名空間名。
請(qǐng)注意,id為“simpleStudent”和“simpleCourse”的兩個(gè)resultMap元素都得到了重用。其中,StudentMapper.xml和CourseMapper.xml中各引用了simpleStudent一次,CourseMapper.xml中引用了simpleCourse兩次。
測(cè)試類如下:
| 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主配置文件,啟動(dòng)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); //獲取選修了此課程的學(xué)生 list = course.getStudents(); length = list.size(); StringBuilder info =?new?StringBuilder("課程名稱:"); info.append(course.getCourseName()); info.append("?? 選修此課程的學(xué)生姓名:"); while(i < length) { info.append(list.get(i).getName()); info.append("?? "); i++; } System.out.println(info.toString()); } } |
執(zhí)行結(jié)果如下:
本文轉(zhuǎn)自 NashMaster2011 51CTO博客,原文鏈接:http://blog.51cto.com/legend2011/1401407,如需轉(zhuǎn)載請(qǐng)自行聯(lián)系原作者 與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖
總結(jié)
以上是生活随笔為你收集整理的MyBatis多对多关联查询示例——MyBatis学习笔记之十八的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。