8、多对一的处理

多对一的理解:

  • 多个学生对应一个老师

  • 如果对于学生这边,就是一个多对一的现象,即从学生这边关联一个老师!

数据库设计

  1. CREATE TABLE `teacher` (
  2. `id` INT(10) NOT NULL,
  3. `name` VARCHAR(30) DEFAULT NULL,
  4. PRIMARY KEY (`id`)
  5. ) ENGINE=INNODB DEFAULT CHARSET=utf8
  6. INSERT INTO teacher(`id`, `name`) VALUES (1, '张老师');
  7. CREATE TABLE `student` (
  8. `id` INT(10) NOT NULL,
  9. `name` VARCHAR(30) DEFAULT NULL,
  10. `tid` INT(10) DEFAULT NULL,
  11. PRIMARY KEY (`id`),
  12. KEY `fktid` (`tid`),
  13. CONSTRAINT `fktid` FOREIGN KEY (`tid`) REFERENCES `teacher` (`id`)
  14. ) ENGINE=INNODB DEFAULT CHARSET=utf8
  15. INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('1', '小明', '1');
  16. INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('2', '小红', '1');
  17. INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('3', '小张', '1');
  18. INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('4', '小李', '1');
  19. INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('5', '小王', '1');

搭建测试环境

1、实体类

  1. public class Teacher {
  2. private int id;
  3. private String name;
  4. //set
  5. //get
  6. }
  7. public class Student {
  8. private int id;
  9. private String name;
  10. //多个学生可以是同一个老师,即多对一
  11. private Teacher teacher;
  12. //set
  13. //get
  14. }

2、编写实体类对应的Mapper接口 【两个】

无论有没有需求,都应该写上,以备后来之需!

  1. public interface StudentMapper {
  2. }
  3. public interface TeacherMapper {
  4. }

3、编写Mapper接口对应的 mapper.xml配置文件 【两个】

无论有没有需求,都应该写上,以备后来之需!

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.chen.mapper.StudentMapper">
  6. </mapper>
  7. <?xml version="1.0" encoding="UTF-8" ?>
  8. <!DOCTYPE mapper
  9. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  10. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  11. <mapper namespace="com.chen.mapper.TeacherMapper">
  12. </mapper>

按查询嵌套处理

1、给StudentMapper接口增加方法

  1. //获取所有学生及对应老师的信息
  2. public List<Student> getStudents();

2、编写对应的Mapper文件

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.chen.mapper.StudentMapper">
  6. <!--
  7. 需求:获取所有学生及对应老师的信息
  8. 思路:
  9. 1. 获取所有学生的信息
  10. 2. 根据获取的学生信息的老师ID->获取该老师的信息
  11. 3. 思考问题,这样学生的结果集中应该包含老师,该如何处理呢,数据库中我们一般使用关联查询?
  12. 1. 做一个结果集映射:StudentTeacher
  13. 2. StudentTeacher结果集的类型为 Student
  14. 3. 学生中老师的属性为teacher,对应数据库中为tid。
  15. 多个 [1,...)学生关联一个老师=> 一对一,一对多
  16. 4. 查看官网找到:association – 一个复杂类型的关联;使用它来处理关联查询
  17. -->
  18. <select id="getStudents" resultMap="StudentTeacher">
  19. select * from student
  20. </select>
  21. <resultMap id="StudentTeacher" type="Student">
  22. <!--association关联属性 property属性名 javaType属性类型 column在多的一方的表中的列名-->
  23. <association property="teacher" column="tid" javaType="Teacher"select="getTeacher"/>
  24. </resultMap>
  25. <!--
  26. 这里传递过来的id,只有一个属性的时候,下面可以写任何值
  27. association中column多参数配置:
  28. column="{key=value,key=value}"
  29. 其实就是键值对的形式,key是传给下个sql的取值名称,value是片段一中sql查询的字段名。
  30. -->
  31. <select id="getTeacher" resultType="teacher">
  32. select * from teacher where id = #{id}
  33. </select>
  34. </mapper>

3、编写完毕去Mybatis配置文件中,注册Mapper!

4、注意点说明:

  1. <resultMap id="StudentTeacher" type="Student">
  2. <!--association关联属性 property属性名 javaType属性类型 column在多的一方的表中的列名-->
  3. <association property="teacher" column="{id=tid,name=tid}"javaType="Teacher" select="getTeacher"/>
  4. </resultMap>
  5. <!--
  6. 这里传递过来的id,只有一个属性的时候,下面可以写任何值
  7. association中column多参数配置:
  8. column="{key=value,key=value}"
  9. 其实就是键值对的形式,key是传给下个sql的取值名称,value是片段一中sql查询的字段名。
  10. -->
  11. <select id="getTeacher" resultType="teacher">
  12. select * from teacher where id = #{id} and name = #{name}
  13. </select>

5、测试

  1. @Test
  2. public void testGetStudents(){
  3. SqlSession session = MybatisUtils.getSession();
  4. StudentMapper mapper = session.getMapper(StudentMapper.class);
  5. List<Student> students = mapper.getStudents();
  6. for (Student student : students){
  7. System.out.println(
  8. "学生名:"+ student.getName()
  9. +"\t老师:"+student.getTeacher().getName());
  10. }
  11. }

按结果嵌套处理

除了上面这种方式,还可以按照结果进行嵌套处理;

1、接口方法编写

  1. public List<Student> getStudents2();

2、编写对应的mapper文件

  1. <!--
  2. 按查询结果嵌套处理
  3. 思路:
  4. 1. 直接查询出结果,进行结果集的映射
  5. -->
  6. <select id="getStudents2" resultMap="StudentTeacher2" >
  7. select s.id sid, s.name sname , t.name tname
  8. from student s,teacher t
  9. where s.tid = t.id
  10. </select>
  11. <resultMap id="StudentTeacher2" type="Student">
  12. <id property="id" column="sid"/>
  13. <result property="name" column="sname"/>
  14. <!--关联对象property 关联对象在Student实体类中的属性-->
  15. <association property="teacher" javaType="Teacher">
  16. <result property="name" column="tname"/>
  17. </association>
  18. </resultMap>

3、去mybatis-config文件中注入

4、测试

  1. @Test
  2. public void testGetStudents2(){
  3. SqlSession session = MybatisUtils.getSession();
  4. StudentMapper mapper = session.getMapper(StudentMapper.class);
  5. List<Student> students = mapper.getStudents2();
  6. for (Student student : students){
  7. System.out.println(
  8. "学生名:"+ student.getName()
  9. +"\t老师:"+student.getTeacher().getName());
  10. }
  11. }

小结

按照查询进行嵌套处理就像SQL中的子查询

按照结果进行嵌套处理就像SQL中的联表查询

9、一对多的处理

一对多的理解:

  • 一个老师拥有多个学生
  • 如果对于老师这边,就是一个一对多的现象,即从一个老师下面拥有一群学生(集合)!

实体类编写

  1. public class Student {
  2. private int id;
  3. private String name;
  4. private int tid;
  5. //set
  6. //get
  7. }
  8. public class Teacher {
  9. private int id;
  10. private String name;
  11. //一个老师多个学生
  12. private List<Student> students;
  13. //set
  14. //get
  15. }

按结果嵌套处理

1、TeacherMapper接口编写方法

  1. //获取指定老师,及老师下的所有学生
  2. public Teacher getTeacher(int id);

2、编写接口对应的Mapper配置文件

  1. <mapper namespace="com.chen.mapper.TeacherMapper">
  2. <!--
  3. 思路:
  4. 1. 从学生表和老师表中查出学生id,学生姓名,老师姓名
  5. 2. 对查询出来的操作做结果集映射
  6. 1. 集合的话,使用collection!
  7. JavaType和ofType都是用来指定对象类型的
  8. JavaType是用来指定pojo中属性的类型
  9. ofType指定的是映射到list集合属性中pojo的类型。
  10. -->
  11. <select id="getTeacher" resultMap="TeacherStudent">
  12. select s.id sid, s.name sname , t.name tname, t.id tid
  13. from student s,teacher t
  14. where s.tid = t.id and t.id=#{id}
  15. </select>
  16. <resultMap id="TeacherStudent" type="Teacher">
  17. <result property="name" column="tname"/>
  18. <collection property="students" ofType="Student">
  19. <result property="id" column="sid" />
  20. <result property="name" column="sname" />
  21. <result property="tid" column="tid" />
  22. </collection>
  23. </resultMap>
  24. </mapper>

3、将Mapper文件注册到MyBatis-config文件中

  1. <mappers>
  2. <mapper resource="mapper/TeacherMapper.xml"/>
  3. </mappers>

4、测试

  1. @Test
  2. public void testGetTeacher(){
  3. SqlSession session = MybatisUtils.getSession();
  4. TeacherMapper mapper = session.getMapper(TeacherMapper.class);
  5. Teacher teacher = mapper.getTeacher(1);
  6. System.out.println(teacher.getName());
  7. System.out.println(teacher.getStudents());
  8. }

按查询嵌套处理

1、TeacherMapper接口编写方法

  1. public Teacher getTeacher2(int id);

2、编写接口对应的Mapper配置文件

  1. <select id="getTeacher2" resultMap="TeacherStudent2">
  2. select * from teacher where id = #{id}
  3. </select>
  4. <resultMap id="TeacherStudent2" type="Teacher">
  5. <!--column是一对多的外键 , 写的是一的主键的列名-->
  6. <collection property="students" javaType="ArrayList" ofType="Student"column="id" select="getStudentByTeacherId"/>
  7. </resultMap>
  8. <select id="getStudentByTeacherId" resultType="Student">
  9. select * from student where tid = #{id}
  10. </select>

3、将Mapper文件注册到MyBatis-config文件中

4、测试

  1. @Test
  2. public void testGetTeacher2(){
  3. SqlSession session = MybatisUtils.getSession();
  4. TeacherMapper mapper = session.getMapper(TeacherMapper.class);
  5. Teacher teacher = mapper.getTeacher2(1);
  6. System.out.println(teacher.getName());
  7. System.out.println(teacher.getStudents());
  8. }

小结

1、关联-association

2、集合-collection

3、所以association是用于一对一和多对一,而collection是用于一对多的关系

4、JavaType和ofType都是用来指定对象类型的

  • JavaType是用来指定pojo中属性的类型
  • ofType指定的是映射到list集合属性中pojo的类型。

注意说明:

1、保证SQL的可读性,尽量通俗易懂

2、根据实际要求,尽量编写性能更高的SQL语句

3、注意属性名和字段不一致的问题

4、注意一对多和多对一 中:字段和属性对应的问题

5、尽量使用Log4j,通过日志来查看自己的错误

MyBatis学习05(多对一和一对多)的更多相关文章

  1. mybatis学习记录六——一对一、一对多和多对多查询

    9       订单商品数据模型 9.1     数据模型分析思路 1.每张表记录的数据内容 分模块对每张表记录的内容进行熟悉,相当 于你学习系统 需求(功能)的过程. 2.每张表重要的字段设置 非空 ...

  2. Mybatis学习4——多对一

    一个用户对多个订单 在用户中添加属性List<user> User.java package pojo; import java.util.Date; import java.util.L ...

  3. Mybatis学习第四天——一对一&&一对多

    两表关系: 1.Mybatis中一对一关系 <!-- 两表联查,通过相同属性user_id left join 表示以左边的表为主表 --> <select id="fin ...

  4. 【MyBatis学习05】SqlMapConfig.xml文件中的配置总结

    经过上两篇博文的总结,对mybatis中的dao开发方法和流程基本掌握了,这一节主要来总结一下mybatis中的全局配置文件SqlMapConfig.xml在开发中的一些常用配置,首先看一下该全局配置 ...

  5. mybatis学习 十五 resultMap标签 一对多

    多次查询,非联合查询版本 <resultMap type="teacher" id="techMap"> <id column="i ...

  6. Mybatis学习(四)————— 高级映射,一对一,一对多,多对多映射

    一.单向和双向 包括一对一,一对多,多对多这三种情况,但是每一种又分为单向和双向,在hibernate中我们就详细解析过这单向和双向是啥意思,在这里,在重复一遍,就拿一对多这种关系来讲,比如有员工和部 ...

  7. 后端框架的学习----mybatis框架(9、多对一处理和一对多处理)

    9.多对一处理和一对多处理 #多对一 <!--按照结果集嵌套查询--> <select id="getAllStudent1" resultMap="S ...

  8. MyBatis 详解(一对一,一对多,多对多)

    1.什么是MyBatis? MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且 ...

  9. 一步步学习NHibernate(5)——多对一,一对多,懒加载(2)

    请注明转载地址:http://www.cnblogs.com/arhat 通过上一章的学习,我们建立了Student和Clazz之间的关联属性,并从Student(many)的一方查看了Clazz的信 ...

随机推荐

  1. 选择适合小企业的CRM软件

    随着信息时代的到来和客户掌握的信息变多,大多数企业开始从"以产品为中心"转变为"以客户为中心".为了适应市场的变化,许多企业开始使用客户关系管理软件来提高工作效 ...

  2. Springboot:@RequestMapping注解及属性详解

    @RequestMapping 注解: @RequestMapping 是 Spring Web 应用程序中最常被用到的注解之一.这个注解会将 HTTP 请求映射到 MVC 和 REST 控制器的处理 ...

  3. springboot整合拦截器如何让其不拦截默认的访问路径

    1.注册自定义拦截器2.拦截器3.控制器4.其它说明:我想做控制拦截登陆,将所有的请求拦截下来判断如果当前的session里没有用户名则跳转到登陆页面.问题是目前可以拦截所有请求了,但第一次进入登陆页 ...

  4. leetcode第156场周赛5207

    当时做的时候,一直理解想搞dp,后面可能思路有点乱了,写不出来... 看了评论区的大佬,才发现是滑动窗口的题目,学习到了. 思路分析: 1.这题可以转化成求数组最大子数组的和不超过maxCost的长度 ...

  5. Leetcode No.1 Two Sum(c++哈希表实现)

    1. 题目 1.1 英文题目 Given an array of integers nums and an integer target, return indices of the two numb ...

  6. kali中设置共享文件夹

    1.在虚拟机设置共享目录 2.查看共享目录命令 root@kali:~# vmware-hgfsclient 3.新建文件夹 root@kali:~# mkdir /mnt/hgfs/ShareDir ...

  7. 3.Java入门

    一.Java帝国的诞生 一场旷日持久的战争 1.C & C++ 1972年C诞生 贴近硬件(有汇编的一些特点),运行极快,效率极高 操作系统,编译器,数据库,网络系统等 指针(能够直接操作内存 ...

  8. 实验 2 Scala 编程初级实践

    实验 2 Scala 编程初级实践 一.实验目的 1.掌握 Scala 语言的基本语法.数据结构和控制结构: 2.掌握面向对象编程的基础知识,能够编写自定义类和特质: 3.掌握函数式编程的基础知识,能 ...

  9. 一、Java预科学习

    1.1.什么是计算机 计算机(computer)俗称电脑,是现代一种用于高速计算的电子计算机器,可以进行数值计算,又可以进行逻辑计算,还具有存储记忆功能.是能够按照程序运行,自动.高速处理海量数据的现 ...

  10. 使用Angular CDK实现一个Service弹出Toast组件

    在Angular中,官方团队在开发Material组件库的同时,顺手做了一套Component dev kit,也就是在Angular世界中大名鼎鼎的CDK,这套工具包提供了非常多的前端开发的通用功能 ...