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,如需转载请自行联系原作者

MyBatis多对多关联查询示例——MyBatis学习笔记之十八相关推荐

  1. OpenCV学习笔记(十八):凸包,最小包围区域算子:convexHull(),minAreaRect(),minEnclosingTriangle(),minEnclosingCircle()

    OpenCV学习笔记(十八):凸包,最小包围区域算子:convexHull(),minAreaRect(),minEnclosingTriangle(),minEnclosingCircle() 1. ...

  2. OpenCV学习笔记(十六)——CamShift研究 OpenCV学习笔记(十七)——运动分析和物体跟踪Video OpenCV学习笔记(十八)——图像的各种变换(cvtColor*+)imgproc

    OpenCV学习笔记(十六)--CamShift研究 CamShitf算法,即Continuously Apative Mean-Shift算法,基本思想就是对视频图像的多帧进行MeanShift运算 ...

  3. MATLAB学习笔记(十八)

    MATLAB学习笔记(十八) 一.Simulink仿真基础 1.1 Simulink的启动 1.2 系统仿真模型的创建 1.3 仿真参数的设置 1.4 总结 二.子系统的创建与封装 2.1 子系统的创 ...

  4. 嵌入式系统设计师学习笔记二十八:嵌入式程序设计③——高级程序设计语言

    嵌入式系统设计师学习笔记二十八:嵌入式程序设计③--高级程序设计语言 解释程序和编译程序 编译器的工作阶段示意图 语法错误:非法字符,关键字或标识符拼写错误 语法错误:语法结构出错,if--endif ...

  5. Mr.J-- jQuery学习笔记(二十八)--DOM操作方法(添加方法总结)

    Table of Contents appendTo appendTo(source, target) 源代码 append prependTo ​ ​ ​ ​ prependTo源码 prepend ...

  6. 计算机二级C语言学习笔记(十八)

    上一篇:计算机二级C语言学习笔记(十七) 程序填空题(二) 题型二:平均值 首先求和,然后将和除以项数 ===================================== ========== ...

  7. Linux学习笔记(十八) -- 运行程序,出现Failed to load module canberra-gtk-module错误的解决方案

    1.错误内容 错误描述 执行程序时,提示如下错误: Failed to load module "canberra-gtk-module" 2.解决方案 (1)执行语句: sudo ...

  8. Dynamic CRM 2013学习笔记(十八)根据主表状态用JS控制子表自定义按钮

    有时要根据主表的审批状态来控制子表上的按钮要不要显示,比如我们有一个需求审批通过后就不能再上传文件了. 首先打开Visual Ribbon Editor, 如下图,我们可以利用Enable Rules ...

  9. 立创eda学习笔记二十八:在嘉立创购买pcb板并贴片(smt)

    完整的写一下,分为两部分: 1.下pcb订单 这个可以看之前写的一个博客: 立创eda学习笔记三:pcb购买_Gutie_bartholomew的博客-CSDN博客 补充一下,买pcb可以直接有几个途 ...

最新文章

  1. 电脑安全注意事项_别墅装修设计注意事项 别墅装修的陷阱有哪些
  2. hdu 1598(最小生成树变形)
  3. 07_NoSQL数据库之Redis数据库:Redis的高级应用之事务处理、持久化操作、pub_sub、虚拟内存
  4. 什么是OLAP和OLTP
  5. h5 兑换商品 页面模版_H5页面制作工具编辑功能对比:木疙瘩、微吾、云
  6. SELinux 基础命令
  7. leetcode 65. Valid Number
  8. HenCoder Android 开发进阶: 自定义 View 1-1 绘制基础
  9. 对外汉语语料库有哪些_燃,9大对外汉语必备语料库,每个都很有“性格”!!...
  10. 临床大数据分析与挖掘
  11. Ant Design for vue
  12. matlab 更换坐标轴_matlab导入数据生成曲线,并更改坐标轴刻度
  13. 用户输入日期利用python简单实现农历转阳历功能(1901-2099年之间)
  14. 浅析数据中心布线系统的绿色环保与节能
  15. 第二届SLAM暑期学校和全国技术论坛有感
  16. arcgis10.2创建新站点报错无权限
  17. vue中通过定时器设置倒计时,5秒倒计时
  18. 一键新机IGRIMACE手机在线源安装方式
  19. 比较有效的Windows10卡硬盘解决方法
  20. 航城街道工商联(商会)领导一行莅临联诚发参观考察

热门文章

  1. pythoncsv数据怎么读_python如何读写csv数据
  2. python cnn图像分类_关于CNN图像分类的一份综合设计指南
  3. abb变频器acs880说明书_常见品牌变频器修改功率方法大全
  4. centos vim 安装插件本质研究
  5. 信息系统项目管理师:第5章:项目范围管理-重点汇总
  6. KVM虚拟机文件优化导出最小化体积的qcow2镜像文件
  7. ASP.NET中MVC默认模板的项目结构
  8. Node提示:npm does not support Node.js v12.16.3
  9. SpringBoot中对thymeleaf的时间进行格式化显示
  10. 使用Shiro的JdbcRealm实现查询数据库进行身份认证