Mybatis05-一对多和多对一处理

多对一和一对多

多对一

多对一的理解:

  • 多个学生对应一个老师

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

结果映射(resultMap):

  • association

    • 一个复杂类型的关联;许多结果将包装成这种类型
    • 嵌套结果映射 —— 关联可以是 resultMap 元素,或是对其它结果映射的引用
  • collection

    • 一个复杂类型的集合
    • 嵌套结果映射 —— 集合可以是 resultMap 元素,或是对其它结果映射的引用

以下使用两种方式实现以下sql语句:

select s.id ,s.name ,t.name from student s,teacher t where s.tid=t.id
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. 实体类STudent和Teacher
public class Teacher {private int id;private String name;public Teacher(){}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "Teacher{" +"id=" + id +", name='" + name + '\'' +'}';}
}
public class Student {private int id;public String getName() {return name;}public void setName(String name) {this.name = name;}private String name;private Teacher teacher;//学生需要关联一个老师public Student(){}public int getId() {return id;}public void setId(int id) {this.id = id;}public Teacher getTeacher() {return teacher;}public void setTeacher(Teacher teacher) {this.teacher = teacher;}@Overridepublic String toString() {return "Student{" +"id=" + id +", name='" + name + '\'' +", teacher=" + teacher +'}';}
}
  1. StudentMapper接口和TeacherMapper
package com.study.dao;
import com.study.pojo.Student;
import java.util.List;public interface StudentMapper {//查询所有的学生信息,以及对应的老师的信息public List<Student> getStudent();
}
public interface TeacherMapper {}
  1. StudentMapper.xml映射文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace绑定一个对应的Dao/Mapper接口的全限定名-->
<mapper namespace="com.study.dao.StudentMapper"><resultMap id="StudentTeacher" type="Student"><!--主键可使用<id>--><result property="id" column="id"/><result property="name" column="name"/><!--复杂的属性,需要单独处理——引用类型:<association>  集合:<collection>--><association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/></resultMap><select id="getStudent" resultMap="StudentTeacher">select * from student</select><select id="getTeacher" resultType="Teacher">select * from teacher where id=#{id}</select>
</mapper>
  1. 核心配置文件
<mappers><mapper class="com.study.dao.TeacherMapper"/><mapper class="com.study.dao.StudentMapper"/>
</mappers>
  1. 测试
@Test
public void testStudent(){SqlSession sqlSession = MybatisUtils.getSqlSession();StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);List<Student> studentList = mapper.getStudent();//动态代理产生一个实现Mapper接口的对象并赋值个,将该对象赋值给接口的引用for (Student student : studentList) {System.out.println(student);}sqlSession.close();
}
2、按结果嵌套处理
  1. StudentMapper接口

    public List<Student> getStudent2();
    
  2. StudentMapper.xml

    <!--===========按照结果嵌套查询==============--><!--按查询结果嵌套处理思路:1. 直接查询出结果,进行结果集的映射-->
    <select id="getStudent2" resultMap="StudentTeacher2">select s.id sid,s.name sname,t.name tnamefrom student s,teacher twhere 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>
  3. 测试

    @Test
    public void testStudent(){SqlSession sqlSession = MybatisUtils.getSqlSession();StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);List<Student> studentList = mapper.getStudent2();//动态代理产生一个实现Mapper接口的对象并赋值个,将该对象赋值给接口的引用for (Student student : studentList) {System.out.println(student);}sqlSession.close();
    }

小结

  • 按照查询进行嵌套处理就像SQL中的子查询
  • 按照结果进行嵌套处理就像SQL中的联表查询
一对多
  1. 实体类

    package com.study.pojo;public class Student {private int id;public String getName() {return name;}public void setName(String name) {this.name = name;}private String name;public int getTid() {return tid;}public void setTid(int tid) {this.tid = tid;}private int tid;public Student(){}public int getId() {return id;}public void setId(int id) {this.id = id;}@Overridepublic String toString() {return "Student{" +"id=" + id +", name='" + name + '\'' +", tid=" + tid +'}';}
    }
    
    package com.study.pojo;import java.util.List;public class Teacher {private int id;private String name;private List<Student> students;//一个老师拥有多个学生public List<Student> getStudents() {return students;}public void setStudents(List<Student> students) {this.students = students;}public Teacher(){}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "Teacher{" +"id=" + id +", name='" + name + '\'' +", students=" + students +'}';}
    }
    
  2. TeacherMapper接口

    List<Teacher> getTeacher();
    
  3. TeacherMapper.xml

    <select id="getTeacher" resultType="Teacher">select * from teacher;
    </select>
    
  4. 核心配置文件中注册Mapper

  5. 测试环境正常

    @Test
    public void test(){SqlSession sqlSession = MybatisUtils.getSqlSession();TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);List<Teacher> teacherList = mapper.getTeacher();for (Teacher teacher : teacherList) {System.out.println(teacher);}sqlSession.close();
    }
    
    1、按结果嵌套查询
    1. TeacherMapper接口`

      Teacher getTeacherById(@Param("tid")int id);
      
    2. TeaccherMapper.xml——按结果嵌套查询

      <!--==================按结果嵌套查询================-->
      <select id="getTeacherById" resultMap="TeacherStudent">select t.name tname,t.id tid,s.id sid,s.name snamefrom student s,teacher twhere s.tid=t.id and t.id=#{tid}
      </select><resultMap id="TeacherStudent" type="Teacher"><result property="id" column="tid"/><result property="name" column="tname"/><!--复杂的属性,需要单独处理——引用类型:<association>  javaType:指定的属性的类型集合:<collection>   集合中的泛型信息,我们使用ofType获取--><!--Teacher实体类中有一个名为students的引用类型的List集合,将List中Student对象的各属性与sql语句返回的字段进行映射--><collection property="students" ofType="Student"><result property="id" column="sid"/><result property="name" column="sname"/><result property="tid" column="tid"/></collection>
      </resultMap>
      
    3. 测试

      @Test
      public void getTeacherById(){SqlSession sqlSession = MybatisUtils.getSqlSession();TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);Teacher teacher = mapper.getTeacherById(1);System.out.println(teacher);sqlSession.close();
      }输出:
      Opening JDBC Connection
      Created connection 1278254413.
      ==>  Preparing: 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=?
      ==> Parameters: 1(Integer)
      <==    Columns: sid, sname, tname, tid
      <==        Row: 1, 小明, 秦老师, 1
      <==        Row: 2, 小红, 秦老师, 1
      <==        Row: 3, 小张, 秦老师, 1
      <==        Row: 4, 小李, 秦老师, 1
      <==        Row: 5, 小王, 秦老师, 1
      <==      Total: 5
      Teacher{id=1, name='秦老师', students=[Student{id=1, name='小明', tid=1}, Student{id=2, name='小红', tid=1}, Student{id=3, name='小张', tid=1}, Student{id=4, name='小李', tid=1}, Student{id=5, name='小王', tid=1}]}
      Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@4c309d4d]
      Returned connection 1278254413 to pool.
      
    2、按照查询嵌套处理
    1. TeacherMapper

      Teacher getTeacherById2(@Param("tid")int id);
      
    2. TeacherMapper.xml

      <!--===========按照查询嵌套处理================-->
      <select id="getTeacherById2" resultMap="TeacherStudent2">select * from mybatis.teacher where id=#{tid}
      </select><resultMap id="TeacherStudent2" type="Teacher"><collection property="students" javaType="ArrayList" ofType="Student" select="getStudentByTeacherId" column="id"/><!--这里的column="id"是teacher表中的id-->
      </resultMap><select id="getStudentByTeacherId" resultType="Student"><!--这里的id是上文中的id-->select * from student where tid=#{id}
      </select>
    3. 测试

          @Testpublic void getTeacherById2() {SqlSession sqlSession = MybatisUtils.getSqlSession();TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);Teacher teacher = mapper.getTeacherById2(1);System.out.println(teacher);sqlSession.close();}输出:
      Opening JDBC Connection
      Created connection 931675031.
      ==>  Preparing: select * from mybatis.teacher where id=?
      ==> Parameters: 1(Integer)
      <==    Columns: id, name
      <==        Row: 1, 秦老师
      ====>  Preparing: select * from student where tid=?
      ====> Parameters: 1(Integer)
      <====    Columns: id, name, tid
      <====        Row: 1, 小明, 1
      <====        Row: 2, 小红, 1
      <====        Row: 3, 小张, 1
      <====        Row: 4, 小李, 1
      <====        Row: 5, 小王, 1
      <====      Total: 5
      <==      Total: 1
      Teacher{id=0, name='秦老师', students=[Student{id=1, name='小明', tid=1}, Student{id=2, name='小红', tid=1}, Student{id=3, name='小张', tid=1}, Student{id=4, name='小李', tid=1}, Student{id=5, name='小王', tid=1}]}
      Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@37883b97]
      Returned connection 931675031 to pool.
      

小结

  • 关联:association【多对一】

  • 集合:collection 【一对多】

  • association是用于一对一和多对一,而collection是用于一对多的关系

  • javaType & ofType

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

注意说明:

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

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

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

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

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

面试高频:

  • Mysql引擎

  • InnoDB底层原理

  • 索引

d=4, name=‘小李’, tid=1}, Student{id=5, name=‘小王’, tid=1}]}
Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@37883b97]
Returned connection 931675031 to pool.
```

小结

  • 关联:association【多对一】

  • 集合:collection 【一对多】

  • association是用于一对一和多对一,而collection是用于一对多的关系

  • javaType & ofType

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

注意说明:

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

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

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

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

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

面试高频:

  • Mysql引擎

  • InnoDB底层原理

  • 索引

  • 索引优化

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

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

相关文章

在线Logo背景去除:pixian.ai

文章目录 简介特色 简介 pixian.ai是一款智能图片背景去除工具&#xff0c;进入网页后&#xff0c;会非常醒目地提示你准备【Free】还是【Paid】&#xff0c;这点就非常好&#xff0c;不向有一些网站&#xff0c;主打免费使用&#xff0c;但时不时弹出“免费注册”&#xff0c…

【微信小程序】连接蓝牙设备

1、检查小程序是否授权蓝牙功能 initBluetooth() {const that thiswx.getSetting({success: (res) > {if (res.authSetting.hasOwnProperty(scope.bluetooth)) {//scope.bluetooth属性存在&#xff0c;且为falseif (!res.authSetting[scope.bluetooth]) {wx.showModal({tit…

Python 连接 MySQL 及 SQL增删改查(主要使用sqlalchemy)

目录 一、环境 二、MySQL的连接和使用 2.1方式一&#xff1a;sql为主 2.1.1创建连接 2.1.2 表结构 2.1.3 新增数据 ​编辑 2.1.4 查看数据 ​编辑 2.1.5 修改数据 2.1.6 删除数据 2.2方式二&#xff1a;orm对象关系映射 2.2.1 mysql连接 2.2.2 创建表 2.2.3 新增…

windows 安装pnpm

安装Node.js&#xff1a; 确保系统上已安装Node.js。pnpm需要Node.js来运行。如果尚未安装Node.js&#xff0c;请从其官方网站下载并安装适用于Windows的最新版本。 安装pnpm&#xff1a; 打开命令行工具&#xff08;如CMD、PowerShell或Git Bash&#xff09;。使用npm&…

解锁机器学习的无限可能:深入探究scikit-learn的强大功能

解锁机器学习的无限可能&#xff1a;深入探究scikit-learn的强大功能 第一部分&#xff1a;背景和功能介绍 在数据科学和机器学习领域&#xff0c;scikit-learn&#xff08;简称sklearn&#xff09;是一个广泛使用的Python库。它提供了简单高效的工具用于数据挖掘和数据分析&a…

【Python短期内快速掌握学习人工智能知识能力】:从零到入门的NLP学习秘籍

⭐️我叫忆_恒心&#xff0c;一名喜欢书写博客的研究生&#x1f468;‍&#x1f393;。 如果觉得本文能帮到您&#xff0c;麻烦点个赞&#x1f44d;呗&#xff01; 近期会不断在专栏里进行更新讲解博客~~~ 有什么问题的小伙伴 欢迎留言提问欧&#xff0c;喜欢的小伙伴给个三连支…

Echarts 在折线图的指定位置绘制一个图标展示

文章目录 需求分析需求 在线段交汇处用一个六边形图标展示 分析 可以使用 markPoint 和 symbol 属性来实现。这是一个更简单和更标准的方法来添加标记点在运行下述代码后,你将在浏览器中看到一个折线图,其中在 [3, 35] (即图表中第四个数据点 Thu 的 y 值为 35 的位置)处…

Java反射Reflect机制详解

文章目录 引言反射的基本概念反射基本原理反射应用场景反射基本使用获取类的Class对象获取构造方法并实例化对象获取和调用方法获取和修改字段反射工具类 反射源码解读获取Class对象的源码调用方法的源码 反射优缺点优点缺点 为什么需要反射总结 引言 Java反射是Java语言中的一…

【干货】视频文件抽帧(opencv和ffmpeg方式对比)

1 废话不多说&#xff0c;直接上代码 opencv方式 import time import subprocess import cv2, os from math import ceildef extract_frames_opencv(video_path, output_folder, frame_rate1):"""使用 OpenCV 从视频中抽取每秒指定帧数的帧,并保存到指定文件夹…

linux系统使用达梦数据库

在Linux系统中使用达梦数据库&#xff0c;首先需要确保已经正确安装了达梦数据库软件。以下是一个基本的使用示例&#xff0c;假设您已经安装了达梦数据库并且配置好了相关环境变量。 连接到数据库&#xff1a; 使用 dsql 命令连接到数据库 dsql -h hostname -u username -p…

宝贝,带上WebAssembly,换个姿势来优化你的前端应用

在你没崛起之前,脸是用来丢的 大家好,我是柒八九。一个专注于前端开发技术/Rust及AI应用知识分享的Coder 此篇文章所涉及到的技术有 WebAssemblyRustWeb Worker(comlink)wasm-packPhotonffmpeg.wasm脚手架生成前端项目因为,行文字数所限,有些概念可能会一带而过亦或者提供对…

BOM是什么东西

BOM&#xff08;Byte Order Mark&#xff0c;字节顺序标记&#xff09;是一个Unicode字符&#xff0c;通常出现在文本文件的开头。它的作用包括以下几个方面&#xff1a; 1. 指示文件的编码方式 BOM可以帮助软件识别文本文件使用的字符编码。不同的编码方式可能会使用不同的B…

经济与安全兼顾:茶饮店购买可燃气体报警器的价格考量

可燃气体报警器在如今的社会中扮演着至关重要的角色。它们用于检测环境中的可燃气体浓度&#xff0c;及早发现潜在的火灾隐患&#xff0c;保护人们的生命和财产安全。 在这篇文章中&#xff0c;佰德将介绍可燃气体报警器的安装、检定以及价格&#xff0c;通过实际案例和数据&a…

PCL 生成空间椭圆点云

目录 一、算法原理二、代码实现三、结果展示本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫。 一、算法原理 设椭圆在 X O Y XOY XOY平面上,参数方程为:

怎么保障TikTok直播网络稳定?

TikTok&#xff0c;这个近年来风靡全球的社交媒体平台&#xff0c;已成为电商引流的新方向&#xff0c;尤其是其直播功能。然而&#xff0c;对于打算进军TikTok直播领域的商家和主播而言&#xff0c;确保网络稳定无疑是首要任务。那么&#xff0c;TikTok直播专线究竟是什么呢&a…

牛啊后续:如何一行C#代码实现解析类型的Summary注释(可用于数据字典快速生成)...

前言&#xff1a;下午有小伙伴要求&#xff0c;让我继续做个解析实体类注释信息的内容。所以我也顺便加入进来。以下开始正文实战操作&#xff1a; 项目需要勾选输出api文档文件。这样就可以让所有实体类的summary信息被写入到输出目录下。如果有多个xml文件也没关系&#xff0…

小程序 UI 风格美不胜收

小程序 UI 风格美不胜收 小程序 UI 风格美不胜收

PostgreSQL的视图pg_stat_replication

PostgreSQL的视图pg_stat_replication pg_stat_replication 是 PostgreSQL 提供的一个系统视图&#xff0c;用于显示主服务器上当前正在进行的复制会话的信息。它可以帮助数据库管理员监控和管理主从复制的状态&#xff0c;确保数据的正确同步和高可靠性。 pg_stat_replicati…

MyEclipse中properties文件中文乱码(Unicode字符)解决办法

程序代码园发文地址&#xff1a;MyEclipse中properties文件中文乱码&#xff08;Unicode字符&#xff09;解决办法-程序代码园小说,Java,HTML,Java小工具,程序代码园,http://www.byqws.com/ ,MyEclipse中properties文件中文乱码&#xff08;Unicode字符&#xff09;解决办法htt…

Django学习三:views业务层中通过models对实体对象进行的增、删、改、查操作。

文章目录 前言一、Django ORM介绍二、项目快速搭建三、操作1、view.pya、增加操作b、删除操作c、修改操作d、查询操作 2、urls.py 前言 上接博文&#xff1a;Django学习二&#xff1a;配置mysql&#xff0c;创建model实例&#xff0c;自动创建数据库表&#xff0c;对mysql数据…