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文件中的idgetByStudentIdselect元素,这里的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

运行结果如下:

wKiom1NX0WuQ9mnBAAGF5yfxGfs220.jpg

现在实现课程端功能,即根据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元素的继承simpleStudentStudentMapper.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());
}
}

执行结果如下:

wKioL1NXzrjyebfJAAGS3KWHa6I873.jpg










本文转自 NashMaster2011 51CTO博客,原文链接:http://blog.51cto.com/legend2011/1401407,如需转载请自行联系原作者
目录
相关文章
|
1月前
|
XML Java 数据库连接
mybatis中在xml文件中通用查询结果列如何使用
mybatis中在xml文件中通用查询结果列如何使用
37 0
|
1月前
|
Java 数据库连接 mybatis
Mybatis 多级分类查询
Mybatis 多级分类查询
17 0
|
2月前
|
Java 关系型数据库 数据库连接
MyBatis Plus 解决大数据量查询慢问题
MyBatis Plus 解决大数据量查询慢问题
|
6天前
|
SQL 缓存 Java
mybatis 一对多查询
mybatis 一对多查询
16 0
|
14天前
|
SQL
MyBatis-Plus-Join关联查询
MyBatis-Plus-Join关联查询
|
14天前
|
SQL XML Java
MyBatis-Plus多表关联查询
MyBatis-Plus多表关联查询
|
19天前
|
SQL XML API
Mybatis-Plus实现查询操作
Mybatis-Plus实现查询操作
18 0
Mybatis-Plus实现查询操作
|
20天前
|
Java 数据库连接 mybatis
MyBatis-Plus查询工具类
MyBatis-Plus是一个MyBatis的增强工具类库,提供了许多实用的查询工具类。
7 0
|
21天前
|
SQL Java 数据库连接
Javaweb之Mybatis的基础操作之查询操作的详细解析
Javaweb之Mybatis的基础操作之查询操作的详细解析
22 0
|
1月前
|
SQL Java 数据库连接
Mybatis查询 出现Unknow colum 'xxxx' in field list 解决办法
Mybatis查询 出现Unknow colum 'xxxx' in field list 解决办法