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,如需转载请自行联系原作者
目录
相关文章
|
2月前
|
Java 数据库连接 数据库
mybatis查询数据,返回的对象少了一个字段
mybatis查询数据,返回的对象少了一个字段
176 8
|
20天前
|
SQL 安全 Java
MyBatis-Plus条件构造器:构建安全、高效的数据库查询
MyBatis-Plus 提供了一套强大的条件构造器(Wrapper),用于构建复杂的数据库查询条件。Wrapper 类允许开发者以链式调用的方式构造查询条件,无需编写繁琐的 SQL 语句,从而提高开发效率并减少 SQL 注入的风险。
13 1
MyBatis-Plus条件构造器:构建安全、高效的数据库查询
|
26天前
|
SQL Java 数据库连接
mybatis如何仅仅查询某个表的几个字段
【10月更文挑战第19天】mybatis如何仅仅查询某个表的几个字段
29 1
|
2月前
|
SQL XML Java
mybatis复习04高级查询 一对多,多对一的映射处理,collection和association标签的使用
文章介绍了MyBatis中高级查询的一对多和多对一映射处理,包括创建数据库表、抽象对应的实体类、使用resultMap中的association和collection标签进行映射处理,以及如何实现级联查询和分步查询。此外,还补充了延迟加载的设置和用法。
mybatis复习04高级查询 一对多,多对一的映射处理,collection和association标签的使用
|
4月前
|
Java 数据库连接 mybatis
Mybatis查询传递单个参数和传递多个参数用法
Mybatis查询传递单个参数和传递多个参数用法
65 11
MybatisPlus-标准CRUD制作,新增boolean save(T t),删除 ~ delete(int id),修改 ~ update(T t),根据id查询,T getById....
MybatisPlus-标准CRUD制作,新增boolean save(T t),删除 ~ delete(int id),修改 ~ update(T t),根据id查询,T getById....
MyBatisPlus如何根据id批量查询?Required request parameter ‘id‘ for method 解决方法是看青戈大佬MybatisPlus的教程
MyBatisPlus如何根据id批量查询?Required request parameter ‘id‘ for method 解决方法是看青戈大佬MybatisPlus的教程
MybatisPlus介绍新增用户,根据id查询,引入MybatisPlus的起步依赖,增删改查最简单的写法
MybatisPlus介绍新增用户,根据id查询,引入MybatisPlus的起步依赖,增删改查最简单的写法
|
5月前
|
Java 数据库连接 mybatis
Mybatis基于注解的一对一和一对多查询
Mybatis基于注解的一对一和一对多查询
|
6月前
|
SQL Java 数据库连接
MyBatis 查询数据库
MyBatis 查询数据库