MySQL中的多对一、一对多关系

· 多对一

如老师和学生,很多个学生由一个老师教,这个时候就是多对一关系。
可以定义学生和老师实体类如下:

@Data
public class Student {private int id;private String name;private Teacher teacher;
}
@Data
public class Teacher {private int id;private String name;
}

数据库存储如下图
teacher表

id name
1 X导
2 吸导

student表

id name tid
1 Salier 1
2 云烟客 1
3 Kaola 2

如何得到所有的学生和它们对应的老师呢
以下代码可以得到所有的学生的信息

   <select id="getStudent" resultType = "Student">select * from mybatis.student;</select>

得到的结果中 teacher对应的是null

那么如何将数据库中student表中的tid和student实体类中的teacher对应起来呢

答案是使用resultMap映射集
我们知道,通过映射集可以将实体类中的元素与数据库中的字段对应起来,完成不同命名的元素之间的数值的映射,但是,将数据库中的 int 类型的 id 映射到实体类 Teacher 上的话,就不能用resultMap中的 result 标签了,在这里,需要用 association 标签。
association 标签通过映射的方式将从 student 表中获得的 tid 以 teacher 对象的形式展示。

得到结果有两种方式,一种是使用子查询的方式,另一种是嵌套查询

首先是子查询

   <select id="getStudent" resultType = "StudentTeacher">select * from mybatis.student;</select><resultMap id="StudentTeacher" type="Student"><result property="id" column="id"/><result property="name" column="name"/><association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/></resultMap>

其中的 association 标签 ,property 为在student实体类中的内容,column 代表着 student 实体类中 teacher对象 将要对应的数据库中的字段,javaType 为要转换的实体类的类型,select 为被嵌套的子方法,该方法如下

        <select id="getTeacher" resultType="Teacher">select * from mybatis.teacher where id = #{tid};</select>

测试以上配置文件能否得到所有学生以及对应的老师

    @Testpublic void getStudent(){SqlSession sqlSession = MybatisUtils.getSqlSession();StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);List<Student> students = mapper.getStudent();for (Student student : students) {System.out.println(student);}sqlSession.close();}

得到运行结果

然后是嵌套查询

代码如下

<select id="getStudent2" resultMap="StudentTeacher2">select s.id sid,s.name sname,t.name tname from mybatis.teacher t,mybatis.student s where s.tid = t.id;
</select><resultMap id="StudentTeacher2" type="Student"><result property="id" column="sid"/><result property="name" column="sname"/><association property="teacher" javaType="Teacher"><result property="name" column="tname"/></association>
</resultMap>

与子查询不同的是,嵌套查询将问题的解决方案完全交给了SQL语句,在 association 标签中,没有再执行第二次查询,而是将 teacher 表中的 name 字段,映射到了SQL语句中的 tname 字段上,从而得到每个学生对应的教师名称。测试后得到的结果如下:

可以得到预期的结果。

· 一对多

像一个老师教很多个学生的情况,就是一对多的关系。
可以定义老师和学生的实体类如下

@Data
public class Student {private int id;private String name;private int tid;
}
@Data
public class Teacher {private int id;private String name;private List<Student> students;
}

在多对一关系中,我们将 student 表中的 tid 字段通过 association 字段映射到了 Student 实体类中的teacher对象上,那么,在一对多关系中,Teacher 实体类中的 Student 泛型的集合应该如何映射?

答案是使用collection标签

collection 可以将数据库中的多个相同字段,映射到一个集合中。

嵌套查询

代码如下:

<select id="getTeacher2" resultMap="StudentTeacher">select s.id sid,s.name sname,t.name tname,t.id tidfrom mybatis.student s,mybatis.teacher twhere s.tid = t.id and t.id = #{tid};
</select><resultMap id="StudentTeacher" type="Teacher"><result property="id" column="tid"/><result property="name" column="tname"/><collection property="students" ofType="Student"><result property="id" column="sid"/><result property="name" column="sname"/><result property="tid" column="tid"/></collection>
</resultMap>

ofType是 collection 标签所映射的集合的泛型的类型

测试代码:

@Testpublic void getTeacher2(){SqlSession sqlSession = MybatisUtils.getSqlSession();TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);Teacher teacher =  mapper.getTeacher2(1);System.out.println(teacher);sqlSession.close();}

代码的测试结果如下:

子查询

代码如下:

<select id="getTeacher" resultMap="StudentTeacher2">select * from mybatis.teacher where id = #{tid};</select><resultMap id="StudentTeacher2" type="Teacher"><collection property="students" javaType="ArrayList" select="getStudentByTeachedID" column="id"/>
</resultMap><select id="getStudentByTeachedID" resultType="Student">select * from mybatis.student where tid = #{tid};
</select>

该部分比较难理解

collection 标签中, property 代表着实体类中的元素名,而数据库中并没有对应的字段,所以 column 字段我们先不写,javaType 是指的 property 所映射的元素的数据类型,为 ArrayList 型。子查询的代码为getStudentByTeachedID 方法,所以 select中为getStudentByTeachedID,最后 getStudentByTeachedID方法可以查询到的 teacher 的 id ,name 所以 我们从中选一个作为前面 property 所对应的 column,即column = " id "。

测试代码:

@Testpublic void getTeacher(){SqlSession sqlSession = MybatisUtils.getSqlSession();TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);Teacher teacher1 = mapper.getTeacher(2);System.out.println(teacher1);sqlSession.close();}

代码运行结果:

Mybatis学习 association关联 和 collection集合相关推荐

  1. 15、mybatis一对多关联查询 collection定义关联集合封装规则及懒加载

    文章目录 1.collection定义关联集合封装规则单步查询 1).Dept增加集合属性 2).DeptMapper增加查询接口 3).DeptMapper.xml增加collection配置 4) ...

  2. Mybatis 一对多关联查询collection用法

    使用resultMap, select 标签, resultMap的中的collection表示一对多,column对应select标签中的sql里的字段或者别名,当两个表字段名称有相同的情况下,可以 ...

  3. mybatis学习之高级映射

    一对一映射查询 1.数据库执行脚本: /* SQLyog Ultimate v12.09 (64 bit) MySQL - 5.7.11-log : Database - db_mybatis *** ...

  4. MyBatis学习总结(五)——实现关联表查询

    2019独角兽企业重金招聘Python工程师标准>>> 一.一对一关联 1.1.提出需求 根据班级id查询班级信息(带老师的信息) 1.2.创建表和数据 创建一张教师表和班级表,这里 ...

  5. MyBatis学习总结(5)——实现关联表查询

    一.一对一关联 1.1.提出需求 根据班级id查询班级信息(带老师的信息) 1.2.创建表和数据 创建一张教师表和班级表,这里我们假设一个老师只负责教一个班,那么老师和班级之间的关系就是一种一对一的关 ...

  6. MyBatis collection的两种形式——MyBatis学习笔记之九

    与association一样,collection元素也有两种形式,现介绍如下: 一.嵌套的resultMap 实际上以前的示例使用的就是这种方法,今天介绍它的另一种写法.还是以教师映射为例,修改映射 ...

  7. mybatis的association以及collection的用法

    在项目中,某些实体类之间肯定有关键关系,比如一对一,一对多等.mybatis 中就用association和collection. association: 一对一关联(has one) collec ...

  8. mybatis中association 和collection 的区别

    mybatis中association 和collection 的区别:https://zhidao.baidu.com/question/1240407172484106299.html 两个实体类 ...

  9. Java学习之容器上(Collection接口常用方法,Iterator接口,使用foreach循环遍历Collection集合元素,Set集合通用知识(Hashset类,hashcode()与Lin

    1.容器API的类图结构如下: JAVA的集合类是一种特别有用的工具类,它可以用于存储数量不等的多个对象,并可以实现常用数据结构,如栈,队列等,除此之外,JAVA集合还可用于保存具有映射关系的关联数组 ...

最新文章

  1. 初识Kubernetes(K8s):理论基础
  2. mSystems:生物地球化学进入病毒时代-采用多样的方法研究病毒和生物地球化学循环...
  3. 74cms 骑士人才系统v3.5.1 正式版
  4. ubuntu设置鼠标单击打开文件夹或者文件
  5. 解密:面部特征点检测的关键技术
  6. oracle查看用户密码时间限制
  7. Ubuntu建立(apache+php+mysql)+phpmyadmin
  8. 基于java二手书论文_java毕业设计_springboot框架的二手书交易管理与实现
  9. linux ssh 远程会话保存,远程SSH会话和流程在断开后运行的5种方法
  10. linux dns中文域名,Linux 搭建中文域名的DNS服务器
  11. Visio studio 2015企业版,汉语版下载,安装,破解,搞定了
  12. python列表数据类型(一分钟读懂)
  13. HDU 5981 2016ICPC大连 K: Guess the number(推理)
  14. 如何突破大众点评接口风控?
  15. 单片机编程软件很简单(一),keil单片机编程软件忽略警告+全局替换
  16. java i586什么意思_linux里面i386 i686 i486 i586代表什么?是什么意思
  17. HTML背景透明到桌面,桌面图标背景透明的设置方法
  18. 旋翼无人机及摄影测量基础
  19. 我对技术的态度是什么样的?
  20. 如何才能成为一名优秀的设计师?

热门文章

  1. GWAS相关名词解释及基础知识储备[长期更新]
  2. 【干货】OJ上各种术语
  3. day79_babasport第五天
  4. vscode 状态栏图标异常问题
  5. CentOS7.6安装图形界面失败,startx执行失败
  6. ubuntu linux编译环境搭建,Ubuntu14.04开发环境搭建
  7. 半双工通信java_Socket实现一个简单的半双工通信
  8. 写一个音乐播放器的微信小程序
  9. 前端的工程化、模块化和组件化
  10. 罗升阳:那两年炼就的Android内功修养