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;
    }

    @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底层原理

  • 索引

  • 索引优化

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Spark安装、解压、配置环境变量、WordCount

Spark 小白的spark学习笔记 2024/5/30 10:14 文章目录 Spark安装解压改名配置spark-env.sh重命名&#xff0c;配置slaves启动查看配置环境变量 工作流程maven创建maven项目配置maven更改pom.xml WordCount按照用户求消费额上传到spark集群上运行 安装 上传&#xff0c;直接拖拽…

RPA-UiBot6.0数据分发机器人—工作通知一键分发

前言 &#x1f4e2;友友们本篇博客的焦点机器人&#xff1a;信息群发机器人&#x1f44b; &#xff08;可以参考小北之前的微信群发助手和校园网更新提示助手两篇博客&#xff09;Uibot (RPA设计软件&#xff09;智能识别信息&#xff0b;微信群发助手&#xff08;升级版&…

Tomcat配置中最大线程数和句柄数分别意义和关系

哈喽&#xff0c;大家好&#xff0c;我是木头左&#xff01; 在Tomcat服务器的配置中&#xff0c;有两个参数是非常重要的&#xff1a;最大线程数和最大句柄数。这两个参数对于服务器的性能和稳定性有着至关重要的影响。本文将详细介绍这两个参数的意义和关系。 1. 最大线程数 …

样式的双向绑定的2种方式,实现样式交互效果

与样式标签实现双向绑定 通过布尔值来决定样式是出现还是消失 show代表着布尔值&#xff0c;show的初始值是false所以文本不会有高亮的效果&#xff0c;当用户点击了按钮&#xff0c;就会调用shows这个函数&#xff0c;并将show的相反值true赋值并覆盖给show,此时show的值为tru…

LangChain入门学习笔记(二)——LangChain表达式语言(LCEL)

基于LangChain框架编写大模型应用的过程就像垒积木&#xff0c;其中的积木就是Prompts&#xff0c;LLMs和各种OutputParser等。如何将这些积木组织起来&#xff0c;除了使用基本Python语法调用对应类的方法&#xff0c;一种更灵活的方法就是使用位于LangChain-Core层中的LCEL&a…

一篇文章彻底搞懂Maven

一、Maven简介 1-Maven介绍 https://maven.apache.org/what-is-maven.html Maven 是自动化构建工具。 Maven 是 Apache 软件基金会组织维护的一款自动化构建工具&#xff0c;专注服务于 Java 平台的项目构建和依赖管理。Maven 这个单词的本意是&#xff1a;专家&#xff0c;内…

这些代码是APP自动化插件开发的关键!

在移动互联网高速发展的今天&#xff0c;APP的自动化插件开发成为了提升应用功能性和用户体验的重要手段。 而在这一过程中&#xff0c;五段源代码的巧妙运用往往能够起到事半功倍的效果&#xff0c;本文将为您科普分享这五段关键的源代码&#xff0c;帮助您更好地理解和应用自…

【Unity】RPG2D龙城纷争(二)关卡、地块

更新日期&#xff1a;2024年6月12日。 项目源码&#xff1a;在第四章发布 索引 简介地块&#xff08;Block&#xff09;一、定义地块类二、地块类型三、地块渲染四、地块索引 关卡&#xff08;Level&#xff09;一、定义关卡类二、关卡基础属性三、地块集合四、关卡初始化五、关…

EDEX-UI这个终端模拟器

eDEX-UI 是一款开源、免费、跨平台的全屏终端模拟器和系统监视器&#xff0c;外观和操作界面极其科幻&#xff0c;灵感来自电影《创战纪》的会议室特效场景。作者倾注了大量心血&#xff0c;使得它不仅拥有酷炫的操作界面&#xff0c;还具备清晰爽脆的音效。 优点&#xff1a; …

使用 PNPM 从 0 搭建 monorepo,测试并发布

1 目标 通过 PNPM 创建一个 monorepo&#xff08;多个项目在一个代码仓库&#xff09;项目&#xff0c;形成一个通用的仓库模板。 这个仓库既可以用于公司存放和管理所有的项目&#xff0c;也可以用于将个人班余的所有积累整合其中。 2 环境要求 核心是 PNPM 和 Node.js&…

万字长文讲解Linux内存管理:伙伴系统

1. buddy system简介&#xff1a; 伙伴系统是内核中用来管理物理内存的一种算法&#xff0c;我们知道内存中有一些是被内核代码占用&#xff0c;还有一些是被特殊用途所保留&#xff0c;那么剩余的空闲内存都会交给内核内存管理系统来进行统一管理和分配。 内核中会把内存按照…

nodejs——原型链污染

一、引用类型皆为对象 原型和原型链都是来源于对象而服务于对象的概念&#xff0c;所以我们要先明确一点&#xff1a; JavaScript中一切引用类型都是对象&#xff0c;对象就是属性的集合。 Array类型、Function类型、Object类型、Date类型、RegExp类型等都是引用类型。 也就…

Codeforces Round 950 (Div. 3) A~F

A.Problem Generator&#xff08;遍历&#xff09; 题意&#xff1a; 弗拉德计划在下个月举行 m m m轮比赛。每轮比赛应包含一个难度为"A"、“B”、“C”、“D”、“E”、"F"和"G"的问题。 弗拉德已经有了一个 n n n个问题的问题库&#xff0…

easyrecovery专业版破解无需注册绿色版免费下载 easyrecovery16数据恢复软件永久激活码密钥百度网盘crack文件

EasyRecovery &#xff08;易恢复中国&#xff09;是由全球著名数据厂商Ontrack 出品的一款数据文件恢复软件。支持恢复不同存储介质数据&#xff1a;硬盘、光盘、U盘/移动硬盘、数码相机、Raid文件恢复等&#xff0c;能恢复包括文档、表格、图片、音视频等各种文件。 开发背景…

解决uview2中u--input输入框禁用状态下click事件不生效

需求&#xff1a;想要点击输入框&#xff0c;展示下拉内容 之前使用uview1是可以直接在input上添加click事件&#xff08;禁用和只读情况下都不影响&#xff09; 但是在uview2上直接写click不生效 解决方式&#xff1a;直接在写click.native"xxx" 代码部分&#x…

什么是有限状态机

标准答案 有限状态机表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型 我自己的理解 有限状态机是状态的改变&#xff0c;比如门的开关、灯的开关等。 执行某些操作&#xff0c;比如推门或按下开关&#xff0c;状态会发生切换。 在这里&#xff0c;我编写一…

LIUNX系统编程:可重入函数volatile

目录 1.概念 2.volatile关键字 1.概念 在执行流执行到mian函数&#xff0c;insert函数中的1号位置的时候&#xff0c;突然就陷入内核&#xff0c;处理信号&#xff0c;执行信号自定义方法&#xff0c;这个方法调用的也是insert&#xff0c;执行完之后&#xff0c;导致了n2的节…

音视频文件格式转换神器(常用JPG、PNG、MP4、MP3转换等)

一、简介 1、一款完全免费、无广告且开源的格式转换工具&#xff0c;支持超过200种文件格式的转换。它能够处理视频、音频、图像、文档、电子书等多种类型的文件&#xff0c;功能非常强大。该软件由GitHub上的一位开发者发布&#xff0c;目的是为了让用户能够轻松地完成文件转换…

C++升级软件时删除老版本软件的桌面快捷方式(附源码)

删除桌面快捷方式其实是删除桌面上的快捷方式文件,那我们如何去删除桌面快捷方式文件呢?软件可能已经发布过多个版本,其中的一些版本的快捷方式文件名称可能做了多次改动,程序中不可能记录每个版本的快捷方式名称,没法直接去删除快捷方式文件。本文就给出一种有效的处理办…

25.入口点注入

钩子注入是利用SetWindowsHookEx函数这是一个被动的注入方式&#xff0c;入口点注入是一个主动注入&#xff0c;就是做这件事什么都不为就是为了注入&#xff0c;入口点注入有很多优势比如说做一个游戏的多开器&#xff0c;多开的检测事情是在游戏一启动的时候完成的&#xff0…