多对一(association)、一对多(collection)

news2024/9/27 21:30:12

1、多对一的处理

多对一的理解:

  • 多个学生对应一个老师
  • 如果对于学生这边,就是多对一的现象,即从学生这边关联一个老师!
1.1、数据库的设计

在这里插入图片描述

CREATE TABLE `teacher` ( 
  `id` INT(10) NOT NULL, 
  `name` VARCHAR(30) DEFAULT NULL, 
  PRIMARY KEY (`id`) 
) ENGINE=INNODB DEFAULT CHARSET=utf8 

INSERT INTO teacher(`id`, `name`) VALUES (1, '秦老师'); 

CREATE TABLE `student` ( 
  `id` INT(10) NOT NULL, 
  `name` VARCHAR(30) DEFAULT NULL, 
  `tid` INT(10) DEFAULT NULL, 
  PRIMARY KEY (`id`), 
  KEY `fktid` (`tid`), 
  CONSTRAINT `fktid` FOREIGN KEY (`tid`) REFERENCES `teacher` (`id`) 
) ENGINE=INNODB DEFAULT CHARSET=utf8 

INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('1', '小明', '1'); 
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('2', '小红', '1'); 
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('3', '小张', '1'); 
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('4', '小李', '1'); 
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('5', '小王', '1');
1.2、搭建测试环境

【Lombok的使用】

  1. IDEA安装Lombok插件
  2. 引入Maven依赖
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --> <dependency> 
  <groupId>org.projectlombok</groupId> 
  <artifactId>lombok</artifactId> 
  <version>1.16.10</version> 
</dependency>

3、在代码中增加注释

@Data //GET,SET,ToString,有参,无参构造 
public class Teacher { 
  private int id; 
  private String name; 
}
@Data public class Student { 
  private int id; 
  private String name; 
  //多个学生可以是同一个老师,即多对一 
  private Teacher teacher; 
}

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

  • 无论有没有需求,都应该写上,以备后来之需!
public interface StudentMapper { 
}
public interface TeacherMapper { 
}

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

  • 无论有没有需求,都应该写上,以备后来之需!
<?xml version="1.0" encoding="UTF-8" ?> 
<!DOCTYPE mapper 
		PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
		"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 
<mapper namespace="com.kuang.mapper.StudentMapper"> 

</mapper>
<?xml version="1.0" encoding="UTF-8" ?> 
<!DOCTYPE mapper 
		PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
		"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 
<mapper namespace="com.kuang.mapper.TeacherMapper"> 

</mapper>
1.3、按查询嵌套处理
  1. 给StudentMapper接口增加方法
//获取所有学生及对应老师的信息 
public List<Student> getStudents();
  1. 编写对应的Mapper文件
<?xml version="1.0" encoding="UTF-8" ?> 
<!DOCTYPE mapper 
		PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
		"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 
<mapper namespace="com.kuang.mapper.StudentMapper"> 
  
  <!-- 
	需求:获取所有学生及对应老师的信息 
	思路:
		1. 获取所有学生的信息 
		2. 根据获取的学生信息的老师ID->获取该老师的信息 
		3. 思考问题,这样学生的结果集中应该包含老师,该如何处理呢,数据库中我们一般 使用关联查询? 
			1. 做一个结果集映射:StudentTeacher 
			2. StudentTeacher结果集的类型为 Student 
			3. 学生中老师的属性为teacher,对应数据库中为tid。 多个 [1,...)学生关联一个老师=> 一对一,一对多 
			4. 查看官网找到:association – 一个复杂类型的关联;使用它来处理关联查 询 
	--> 
  <select id="getStudents" resultMap="StudentTeacher"> 
    select * from student 
  </select> 
  <resultMap id="StudentTeacher" type="Student"> 
    <!--association关联属性 property属性名 javaType属性类型 column在多的一方的表中的列名--> 
    <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/> 
  </resultMap> 
  
  <!-- 
		这里传递过来的id,只有一个属性的时候,下面可以写任何值 
		association中column多参数配置: 
			column="{key=value,key=value}" 
			其实就是键值对的形式,key是传给下个sql的取值名称,value是片段一中sql查询的 字段名。
	--> 
  <select id="getTeacher" resultType="teacher"> 
    select * from teacher where id = #{id} 
  </select> 
</mapper>

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

4、注意点说明:

<resultMap id="StudentTeacher" type="Student"> 
  <!--association关联属性 property属性名 javaType属性类型 column在多的一方 的表中的列名--> 
  <association property="teacher" column="{id=tid,name=tid}"javaType="Teacher" select="getTeacher"/> 
</resultMap> 

<!-- 
这里传递过来的id,只有一个属性的时候,下面可以写任何值 
association中column多参数配置: 
		column="{key=value,key=value}" 
		其实就是键值对的形式,key是传给下个sql的取值名称,value是片段一中sql查询的字段名。
--> 
<select id="getTeacher" resultType="teacher"> 
  select * from teacher where id = #{id} and name = #{name} 
</select>

5、测试

@Test public void testGetStudents(){ 
  SqlSession session = MybatisUtils.getSession(); 
  StudentMapper mapper = session.getMapper(StudentMapper.class); 
  List<Student> students = mapper.getStudents(); 
  for (Student student : students){ 
    System.out.println( "学生名:"+ student.getName() 
                       +"\t老师:"+student.getTeacher().getName()); 
  } 
}
1.4、按结果嵌套处理

除了上面这种方式,还有其他思路吗?

我们还可以按照结果进行嵌套处理;

  1. 接口方法编写
public List<Student> getStudents2();

2、编写对应的mapper文件

<!-- 
按查询结果嵌套处理 
思路:
	1. 直接查询出结果,进行结果集的映射 
--> 
<select id="getStudents2" resultMap="StudentTeacher2" > 
  select s.id sid, s.name sname , t.name tname from student s,teacher t where s.tid = t.id 
</select> 
<resultMap id="StudentTeacher2" type="Student"> 
  <id property="id" column="sid"/>
  <result property="name" column="sname"/> 
  <!--关联对象property 关联对象在Student实体类中的属性--> 
  <association property="teacher" javaType="Teacher"> 
    <result property="name" column="tname"/> 
  </association> 
</resultMap>

3、去mybatis-confifig文件中注入【此处应该处理过了】

4、测试

@Test public void testGetStudents2(){ 
  SqlSession session = MybatisUtils.getSession(); 
  StudentMapper mapper = session.getMapper(StudentMapper.class); 
  List<Student> students = mapper.getStudents2(); 
  for (Student student : students){ 
    System.out.println( "学生名:"+ student.getName() 
                       +"\t老师:"+student.getTeacher().getName()); 
  } 
}
1.5、小结
  • 按照查询进行嵌套处理就像SQL中的子查询
  • 按照结果进行嵌套处理就像SQL中的联表查询

2、一对多的处理

一对多的理解:

  • 一个老师拥有多个学生
  • 如果对于老师这边,就是一对多的现象,即从一个老师下面拥有一群学生(集合)!
2.1、实体类的编写
@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; 
}

… 和之前一样,搭建测试的环境!

2.2、按结果嵌套处理
  1. TeacherMapper接口编写方法
//获取指定老师,及老师下的所有学生 
public Teacher getTeacher(int id);

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

<mapper namespace="com.kuang.mapper.TeacherMapper"> 
  
  <!-- 
		思路:
			1. 从学生表和老师表中查出学生id,学生姓名,老师姓名 
			2. 对查询出来的操作做结果集映射 
					1. 集合的话,使用collection! 
						JavaType和ofType都是用来指定对象类型的 
						JavaType是用来指定pojo中属性的类型 
						ofType指定的是映射到list集合属性中pojo的类型。 
	--> 
  <select id="getTeacher" resultMap="TeacherStudent"> 
    select s.id sid, s.name sname , t.name tname, t.id tid 
    from student s,teacher t where s.tid = t.id and t.id=#{id} 
  </select> 
  
  <resultMap id="TeacherStudent" type="Teacher"> 
    <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> 
</mapper>

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

<mappers> 
  <mapper resource="mapper/TeacherMapper.xml"/> 
</mappers>

4、测试

@Test public void testGetTeacher(){ 
  SqlSession session = MybatisUtils.getSession(); 
  TeacherMapper mapper = session.getMapper(TeacherMapper.class); 
  Teacher teacher = mapper.getTeacher(1);	
  System.out.println(teacher.getName());
  System.out.println(teacher.getStudents()); 
}
2.3、按查询嵌套处理
  1. TeacherMapper接口编写方法
public Teacher getTeacher2(int id);

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

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

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

4、测试

@Test public void testGetTeacher2(){ 
  SqlSession session = MybatisUtils.getSession(); 
  TeacherMapper mapper = session.getMapper(TeacherMapper.class); 
  Teacher teacher = mapper.getTeacher2(1);
  System.out.println(teacher.getName());
  System.out.println(teacher.getStudents()); 
}
2.4、小结
  1. 关联-association

  2. 集合-collection

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

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

    • JavaType是用来指定pojo中属性的类型

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

注意说明:

  1. 保证SQL的可读性,尽量通俗易懂
  2. 根据实际要求,尽量编写性能更高的SQL语句
  3. 注意属性名和字段不一致的问题
  4. 注意一对多和多对一 中:字段和属性对应的问题
  5. 尽量使用Log4j,通过日志来查看自己的错误

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/637395.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Apple Vision Pro -开始使用visionOS

Apple Vision Pro -开始使用visionOS visionOS将熟悉的框架和全新的概念结合在一起&#xff0c;因此您可以为空间计算构建一个全新的应用程序世界。为了帮助您开始您的旅程&#xff0c;我们将介绍一系列会议&#xff0c;涵盖空间计算的构建块以及为该平台设计应用程序和游戏。…

软件开发模型

一、 概述   软件开发模型(Software Development Model)是指软件开发全部过程、活动和任务的结构框架。软件开发包括需求、设计、编码、测试和维护 阶段。   软件开发模型能清晰、直观地表达软件开发全过程&#xff0c;明确规定了要完成的主要活动和任务&#xff0c;用来作…

rider发布项目报错:[MSB4057] 该项目中不存在目标“WebPublish”。

情景再现 Rider升级到2022.3版本及以上时&#xff0c;发布项目显示&#xff1a; [MSB4057] 该项目中不存在目标“WebPublish”。 或者显示 Error:Current toolset does not support publishing for non-Core ASP.NET projects 原因 这是因为Rider MSBuild版本不一致导致。 解…

基于javaweb(springboot+mybatis)宠物医院预约管理系统设计和实现以及论文报告

基于javaweb(springbootmybatis)宠物医院预约管理系统设计和实现以及论文报告 博主介绍&#xff1a;5年java开发经验&#xff0c;专注Java开发、定制、远程、指导等,csdn特邀作者、专注于Java技术领域 作者主页 超级帅帅吴 Java项目精品实战案例《500套》 欢迎点赞 收藏 ⭐留言…

参会记录 | 北京智源大会-基础模型前沿技术论坛

2023年6月10日上午&#xff0c;线上参与了北京智源大会&#xff0c;主要观看了2023北京智源大会-基础模型前沿技术论坛&#xff0c;以下是论坛中比较感兴趣的点和思考。 本次论坛的演讲嘉宾如下&#xff1a; 上述嘉宾有来自业界的刘胤晗老师和周彦祺老师&#xff0c;也有来自…

【06】STM32·HAL库开发-STM系统框架 | STM32寻址范围 | STM32存储器映射 | STM32寄存器映射

目录 1.STM32系统框架&#xff08;了解&#xff09;1.1Cortex M内核 & 芯片1.2F1系统架构1.2.1F1系统框架简图1.2.2F1系统框架总图 1.3F4系统架构1.3.1F4系统框架简图&#xff08;F407为例&#xff09;1.3.2F4系统框架总图 1.4F7系统架构1.4.1多重AHB总线矩阵1.4.2F7系统结…

如何防止U盘复制电脑文件?

在我们的工作中&#xff0c;经常需要将重要的文件存在电脑中&#xff0c;我们必须要妥善的保护这些重要数据&#xff0c;那么该如何防止U盘复制电脑中的文件呢&#xff1f; 要想防止U盘复制电脑文件&#xff0c;可从三个方面入手&#xff0c;分别是&#xff1a; 禁止电脑使用U…

吴恩达471机器学习入门课程1第2周——线性回归(单变量)

文章目录 Linear Regression1 导包2 - 问题陈述3 - 数据集可视化数据 4 - 线性回归复习5 - 计算代价代价函数模型预测实现 6 - 梯度下降批量梯度下降法学习参数 Linear Regression 您将使用一个变量实现线性回归&#xff0c;以预测餐厅特许经营的利润。 1 导包 首先&#xf…

【电路】电路与电子技术基础 课堂笔记 第12章 集成逻辑门电路

12.4 正逻辑与负逻辑 正负逻辑转换规则 正负逻辑符号

2023 华为 Datacom-HCIE 真题题库 (6月11新增部分)--含解析

单项选择题 1.[试题编号:263143] (单选题)华为CloudCampus位置服务(wifi方案),获取基于在wifi的位置数据,并上报至开发者的LBS应用。开发者可以使用数据,计算范围内的wi-fi终端位置信息。对于LBS位置应用和iMaster NCE的交互流程,以下哪项是错误的?(单选)单选 A、LBS…

Vue中如何进行Markdown编辑与渲染?

Vue中如何进行Markdown编辑与渲染&#xff1f; Markdown是一种轻量级的标记语言&#xff0c;广泛用于编写技术文档、博客、论坛等。Vue.js是一款流行的JavaScript框架&#xff0c;它提供了一些有用的工具来处理DOM元素和用户界面。在Vue中&#xff0c;我们可以使用一些库和组件…

除了Midjourney和Stable Diffusion,还有哪些AI模型可以使用

Midjourney是一款广受设计师和艺术家欢迎的人工智能图像生成器。然而&#xff0c;最近它停止提供免费试用&#xff0c;让许多用户开始寻找替代品。在本文中&#xff0c;我们为您编制了一个2023年可尝试的十大Midjourney替代品列表。我们包括了免费和付费选项&#xff0c;让您可…

Hutool工具类库之图片验证码

文章目录 一、介绍二、示例1、LineCaptcha 线段干扰的验证码2、CircleCaptcha 圆圈干扰验证码3、ShearCaptcha 扭曲干扰验证码4、GifCaptcha 验证码5、写出到浏览器&#xff08;Servlet输出&#xff09;6、自定义验证码 一、介绍 验证码功能位于 cn.hutool.captcha 包中&#x…

【电路】电路与电子技术基础 课堂笔记 第13章 组合逻辑电路的分析与设计

组合逻辑电路&#xff1a;任意时刻的输出稳定状态仅仅取决于该时刻的输入信号&#xff0c;而与输入信号作用前电路所处的状态无关。 13.1 组合逻辑电路分析 13.1.2 加法器电路分析 S就是Sum&#xff0c;CO 就是Carry-Over&#xff08;进位&#xff09;。 算术运算是数字系统的…

ROS学习——通信机制(参数服务器)

一、引言 参数服务器在ROS中主要用于实现不同节点之间的数据共享。参数服务器相当于是独立于所有节点的一个公共容器&#xff0c;可以将数据存储在该容器中&#xff0c;被不同的节点调用&#xff0c;当然不同的节点也可以往其中存储数据&#xff0c;关于参数服务器的典型应用场…

【c++】组合类+继承情况下构造顺序

组合类继承情况下构造顺序 构造顺序同普通继承&#xff0c;先父后子&#xff0c;内部类是最老的&#xff08;最先调用构造的&#xff09;。 示例代码 class A { public:A(int a 0):_a(a){cout << "A()" << endl;}~A(){cout << "~A()" …

如何将本地python项目部署到阿里云服务器上(完整版)

一、准备阿里云服务器 首先在阿里云服务器免费试用网站中选择相应的服务器&#xff0c;本次搭建选择的服务器是适合入门级开发者的服务器。在阿里云控制台上创建一个云服务器&#xff08; ECS 实例&#xff09;并获取访问凭证&#xff0c;包括主机 IP 地址、用户名和密码。在服…

K Shortest Paths算法之Eppstein algorithm

Eppstein的算法是David Eppstein于1998年提出的一种高效且易于实现的k条最短路径寻找方法。它的时间复杂度为O(m n log n k)&#xff0c;其中m是边的数量&#xff0c;n是节点的数量&#xff0c;k是要寻找的路径数。相较于其他方法&#xff0c;它具有较好的性能和实用性。 Epp…

路漫漫其修远兮

其实不仅是专业&#xff0c;AI冲击波才刚刚开启&#xff0c;包括博客、自媒体作用也在大幅度下降呢。 很多人看过如下这幅图&#xff1a; 提示工程师确实是在当前大型语言模型不够完善的情况下&#xff0c;通过微调输入的方式来提高模型的性能。随着模型的迭代&#xff0c;这些…

算法模板(8):网络流(1):最大流

算法模板&#xff08;8&#xff09;&#xff1a;网络流&#xff08;1&#xff09;&#xff1a;最大流 网络流基本概念 基本概念 流网络&#xff0c;不考虑反向边可行流&#xff0c;不考虑反向边 两个条件&#xff08;根据《算法导论》&#xff0c;这两个条件可以看作可行流的充…