Mybatis05-一对多和多对一处理

news2024/11/15 23:44:59

多对一和一对多

多对一

多对一的理解:

  • 多个学生对应一个老师

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

结果映射(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;
    }

    @Override
    public 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;
    }

    @Override
    public 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 mapper
        PUBLIC "-//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 tname
        from student s,teacher t
        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>
    
    
  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;
        }
    
        @Override
        public 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;
        }
    
        @Override
        public 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 sname
          from student s,teacher t
          where 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. 测试

          @Test
          public 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.coloradmin.cn/o/1812934.html

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

相关文章

扩展学习|风险管理的文献综述汇总(持续更新向)

一、风险管理发展历程和趋势综述&#xff08;2007年发表&#xff09; 文献来源&#xff1a;[1]严复海,党星,颜文虎.风险管理发展历程和趋势综述[J].管理现代化, 2007(2):4.DOI:CNKI:SUN:GLXX.0.2007-02-009. 简介&#xff1a;该文以风险管理发展历程中的大事件为线索, 对风险管…

设计模式-享元模式(结构型)

享元模式 享元模式是一种结构型模式&#xff0c;它主要用于减少创建对象的数量&#xff0c;减少内存占用。通过重用现有对象的方式&#xff0c;如果未找到匹配对象则新建对象。线程池、数据库连接池、常量池等池化的思想就是享元模式的一种应用。 图解 角色 享元工厂&#xf…

Nginx05-负载均衡详解、LNMP+NFS、会话保持、负载均衡状态检查upstream-check、平滑升级

目录 写在前面Nginx05Nginx 负载均衡&#xff08;upstream模块&#xff09;概述常见选择负载均衡和反向代理的区别Nginx负载均衡的方式Nginx运行状况检查备份服务器Nginx upstream模块选项说明 实验1 负载均衡两台frontfront配置lb01配置测试流程梳理 实验2 LNMPNFS小实验NFS配…

网络安全课程开发

我们为卡巴斯基实验室开发了一个交钥匙教育门户网站&#xff0c;并为其开设了网络安全课程。在资源上&#xff0c;你可以熟悉课程的理论部分-观看视频或阅读插图文本版本&#xff0c;然后通过回答问题来验证你的知识。通过最终测试后&#xff0c;用户将获得证书。 对于这个项目…

hive 安装 嵌入模式 笔记

$ hive $ HIVE_HOME/bin/schematool -dbType derby –initSchema $ schematool -verbose -validate -dbType derby $HIVE_HOME/bin/hiveserver2 这个启动了先不要关闭&#xff0c;再打开一个终端进行下面的步骤 Beeline -u show databases 总结 报错1 WARN jdbc.HiveConnecti…

【ARM Cache 及 MMU 系列文章 6.4 -- ARMv8/v9 如何读取 Cache Tag 及分析其数据?】

请阅读【ARM Cache 及 MMU/MPU 系列文章专栏导读】 及【嵌入式开发学习必备专栏】 文章目录 Cache Tag 数据读取测试代码Cache Tag 数据读取 在处理器中,缓存是一种快速存储资源,用于减少访问主内存时的延迟。缓存通过存储主内存中经常访问的数据来实现这一点。为了有效地管…

图钉AI导航

1、图钉AI导航 https://www.tudingai.com/

应急物资管理系统|DW-S300构筑现代化战备保障的利器

行业背景 智慧应急物资管理系统&#xff08;智物资DW-S300&#xff09;是一套成熟系统&#xff0c;依托互3D技术、云计算、大数据、RFID技术、数据库技术、AI、视频分析技术对RFID智能仓库进行统一管理、分析的信息化、智能化、规范化的系统。 政府相关部门设立的应急物资库是…

Python pickle反序列化

基础知识 Pickle Pickle在Python中是一个用于序列化&#xff08;将对象转换为字节流&#xff09;和反序列化&#xff08;将字节流转换回对象&#xff09;的标准库模块。它主要用于将Python对象保存到文件或通过网络进行传输&#xff0c;使得数据可以跨会话和不同的Python程序共…

面试题:缓存穿透,缓存击穿,缓存雪崩

1 穿透: 两边都不存在&#xff08;皇帝的新装&#xff09; ——简介&#xff1a;缓存穿透指的是恶意用户或攻击者通过请求不存在于缓存和后端存储中的数据来使得所有请求都落到后端存储上&#xff0c;导致系统瘫痪。 ——详述&#xff1a;(缓存穿透是指查询一个一定不存在的数…

【lesson7】服务端业务处理模块实现

文章目录 业务处理实现思路业务处理类设计成员变量成员函数RunModuleupLoadlistShowdownLoadgetETagInfo 业务处理实现思路 云备份项目中 &#xff0c;业务处理模块是针对客户端的业务请求进行处理&#xff0c;并最终给与响应。而整个过程中包含以下要实现的功能&#xff1a; …

通过微软提供的工具制作win10启动盘

1.到如下链接下载微软提供的工具&#xff1a;MediaCreationTool_22H2.exe https://www.microsoft.com/zh-cn/software-download/windows10 2.启动该工具&#xff0c;选择下面选项&#xff0c;根据提示一步步操作即可&#xff08;注意&#xff1a;要提前准备一个实际空间大于8…

javaWeb项目-ssm+vue学生成绩管理系统功能介绍

本项目源码&#xff1a;java基于SSMVUE学生成绩管理系统源码文档资料资源-CSDN文库 项目关键技术 开发工具&#xff1a;IDEA 、Eclipse 编程语言: Java 数据库: MySQL5.7 框架&#xff1a;ssm、Springboot 前端&#xff1a;Vue、ElementUI 关键技术&#xff1a;springboot、SS…

Keil uVision5复制到Word文档后乱码的解决办法

一、问题出现状况 在做嵌入式实验时&#xff0c;我发现在Keil uVision5中正常编写的代码和注释&#xff0c;写入实验报告&#xff08;word&#xff09;中其中文注释就会产生乱码&#xff0c;非常不美观&#xff0c;并且使代码变得杂乱。 如下&#xff1a;Keil uVision5中注释…

最新区块链论文速读--CCF A会议 CCS 2023 共25篇 附pdf下载(4/4)

Conference&#xff1a;ACM Conference on Computer and Communications Security (CCS) CCF level&#xff1a;CCF A Categories&#xff1a;network and information security Year&#xff1a;2023 Num&#xff1a;25 第1~7篇区块链文章请点击此处查看 第8~13篇区块链文…

leetcode 1336 每次访问的交易次数(postgresql)

需求 表: Visits ---------------------- | Column Name | Type | ---------------------- | user_id | int | | visit_date | date | ---------------------- (user_id, visit_date) 是该表的主键 该表的每行表示 user_id 在 visit_date 访问了银行 表: Transactions ----…

用Fay搭建了数字人

文章目录 流程server端ue端 小结 流程 大概是这么一个流程&#xff0c;先去配置server端&#xff0c;然后去配置ue端代码&#xff0c;再接着去android端的。一步一步来&#xff0c;一起学习学习。 server端 去git下载开源代码&#xff0c;然后按照指引一步一个脚印往下走。如…

未来之城:SIGMOD 2024大会在智利圣地亚哥点燃智能革命之火

会议之眼 快讯 2024 年 ACM SIGMOD Conference&#xff08;国际数据管理大会&#xff09;正在于 6月9日至6月14日在智利圣地亚哥举行。它由美国计算机学会&#xff08;ACM&#xff09;的数据管理特别兴趣小组&#xff08;SIGMOD&#xff09;主办&#xff0c;是中国计算机学会&…

7个强大的文字转语音TTS引擎

大家好&#xff0c;文本到语音&#xff08;TTS&#xff09;技术让机器能以人声般自然地“说话”&#xff0c;架起了人机沟通的新桥梁。开源TTS引擎以其开放性和经济性&#xff0c;成为热门工具&#xff0c;为智能应用注入活力。 文本到语音&#xff08;TTS&#xff09;引擎&am…

JVM 根可达算法

Java中的垃圾 Java中"垃圾"通常指的是不再被程序使用和引用的对象&#xff0c;具体表现在没有被栈、JNI指针和永久代对象所引用的对象。Java作为一种面向对象的编程语言&#xff0c;它使用自动内存管理机制&#xff0c;其中垃圾收集器负责检测和回收不再被程序引用的…