如何使用mybatis处理数据库关系中的一对多关系呢?

news2025/2/25 11:51:09

测试环境的搭建:

本篇文章的测试环境搭建和上篇文章基本相似,这里在上篇文章传送门测试环境的基础上进行对比和修改!

上篇文章所提到的多对一是多个学生对应一个老师,是在学生的角度去获取老师的信息,而本篇文章的一对多,是在老师的角度去获取对应学生的信息

新建实体类:

在实体类上,与上篇文章中的多对一不同的地方在于:

多对一:老师作为学生的一个属性
而这里的一对多:学生作为老师的一个属性

Student类:

package pojo;
import lombok.Data;

@Data
public class Student {
    private int id;
    private String name;
    private int tid;
}

teacher类:

package pojo;
import lombok.Data;
import java.util.List;

@Data
public class Teacher {
    private int id;
    private String name;
    //一个老师拥有多个学生
    private List<Student> students;
}

注:数据库中表的创建和数据的插入步骤,与上篇文章的多对一完全相同,这里不再进行展示

新建Mapper接口:

student_Mapper接口:

package dao;
public interface student_Mapper {
}

teacher_Mapper接口:

package dao;
import pojo.Teacher;
import java.util.List;

public interface teacher_Mapper {
   //获取老师
    List<Teacher> getTeacher();
}

建立Mapper.xml文件:

student_Mapper.xml文件:

由于一对多是多个学生作为老师的属性,SQL语句自然是在teacher_Mapper.xml文件中进行书写,所以这里只需要绑定对应的接口,无需再进行其他操作

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="dao.student_Mapper">
</mapper>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="dao.teacher_Mapper">
        <select id="getTeacher" resultType="Teacher">
            select * from teacher;
        </select>
</mapper>

在核心配置文件[mybatis-config.xml]中绑定注册我们的Mapper接口或者文件:

由于是查询老师的有关信息,因此,这里绑定的为老师的接口teacher_Mapper

代码如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
    <typeAliases>
        <package name="pojo"/>
    </typeAliases>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=false&amp;useUnicode=true&amp;characterEncoding=utf-8"/>
                <property name="username" value="root"/>
                <property name="password" value="xxx"/>
            </dataSource>
        </environment>
    </environments>


    <mappers>
        <mapper class="dao.teacher_Mapper"/>
    </mappers>


</configuration>

通过查询数据测试环境是否搭建成功:

package dao.user;
import dao.teacher_Mapper;
import pojo.Teacher;
import utils.mybatis_utils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;

public class test{
    @Test
    public void getUserByLimit(){
        SqlSession sqlSession= mybatis_utils.getSqlSession();
        teacher_Mapper teacher_mapper=sqlSession.getMapper(teacher_Mapper.class);
        
        List<Teacher> teacherList=teacher_mapper.getTeacher();
        System.out.println(teacherList);
        
        sqlSession.close();
    }
}

关于测试环境还有所需的三个文件,分别是:两个pom.xml文件,以及mybatis_utils类,在这篇文章有相应的代码,这里就不过多赘述了

输出部分结果如下:

测试成功!

在这里插入图片描述

但通过输出结果,我们不难发现,这里搭建的测试环境的输出结果,和多对一的关系一样,同样出现了students为null的现象,原因嘛,和上篇文章是相似的,不懂得小伙伴移步上篇文章,这里我们只给出具体的解决办法

一对多处理:

获取指定老师下的所有学生及老师的信息

在这里插入图片描述

按照查询嵌套处理:

方法如下:

基本与多对一的方法相似,唯一让人迷惑的就是这里为什么既有javaType还有ofType呢?

javaType用来指定对象所属的java数据类型,在多对一的关系中,多个学生对应一个老师,因此javaType的类型为Teacher,而在这里一个老师对应多个学生,那么javaType的类型可不是Student而是List,因为在实体类Teacher中students的类型就是ArrayList

ofType指定的是映射到list集合属性中泛型的类型,在一对多的关系中,学生[Student类]作为list集合的类型,因此ofType的值为Student

在这里插入图片描述

代码如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="dao.teacher_Mapper">
    <select id="getTeacher2" resultMap="TeacherStudent">
            select * from teacher where id=#{tid};
    </select>
    <resultMap id="TeacherStudent" type="Teacher">
        <collection property="students" column="id" javaType="ArrayList" ofType="Student" select="getStudent"/>
    </resultMap>
    <select id="getStudent" resultType="Student">
        select * from student  where tid=#{tid};
    </select>
</mapper>

按照结果嵌套处理:

在teacher_Mapper接口中编写方法:

package dao;
import org.apache.ibatis.annotations.Param;
import pojo.Teacher;

public interface teacher_Mapper {
    //获取指定老师下的所有学生及老师的信息
    Teacher getTeacher2(@Param("tid") int id);
}

在teacher_Mapper.xml文件中编写对应的SQL语句:

与多对一不同的是,这里我们对于复杂属性的处理是通过collection,而不是association,原因是多对一中,老师对于学生来说是一个对象,而这里的学生对于老师来说,是一个集合,association后面对应的是JavaType,而collection对应的是ofType,虽然它们的名称不同,但都指的是java类

在这里插入图片描述

代码如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="dao.teacher_Mapper">
        <select id="getTeacher2" 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=#{tid}
        </select>
    <resultMap id="TeacherStudent" type="Teacher">
        <result property="id" column="tid"/>
        <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>

测试类代码如下:

package dao.user;
import dao.teacher_Mapper;
import pojo.Teacher;
import utils.mybatis_utils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

public class test{
    @Test
    public void getUserByLimit(){
        SqlSession sqlSession= mybatis_utils.getSqlSession();
        teacher_Mapper teacher_mapper=sqlSession.getMapper(teacher_Mapper.class);

        Teacher teacherList=teacher_mapper.getTeacher2(1);
        System.out.println(teacherList);

        sqlSession.close();
    }
}

部分输出结果如下:

无论上按照查询嵌套处理还是结果嵌套处理,都能够查询到正确的结果,大家可以根据自身情况,选择最适合自己的方法

在这里插入图片描述

最后提醒一些注意点:

1:关联----association[多对一]     集合----collection[一对多]
2:javaType:用来指定实体类中的属性类型      ofType:用来指定映射到List或集合中的pojo类型,也就是泛型中的约束类型
3:编写的SQL语句应保证可读性强
4:注意一对一和多对一中的属性名和字段问题

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

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

相关文章

关于MySQL中的数据类型

一、常见的数据类型有&#xff1a; varchar&#xff08;最长255&#xff09;&#xff1a;【每个长度可以保存一个英文字符或一个汉字】 可变长度字符串 比较智能 节省空间 会根据实际的数据长度动态分配空间 优点&#xff1a;节省空间 缺点&#xff1a;需要动态分配空间&am…

phy-MDC时钟修改

问题分析:我们这边更换一种电平转换芯片&#xff0c;还是没调通。可能一个原因是这个芯片在开漏模式下速速最高到2M有关&#xff0c;您那边能帮忙协调一下&#xff0c;把内核PHY的MDC时钟改为2M以下&#xff0c;另把PHY的复位时间由现在的13MS左右调整到30MS左右我们试一下 在…

数据库知识学习

关系型数据库学习 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录关系型数据库学习一 数据库介绍1 相关定义数据&#xf…

基于卷积神经网络识别金融票据中的文字信息(计算机毕设完整代码可直接运行)

结果展示&#xff1a;用户首先通过”浏览文件”按钮选择扫描获得的金融票据图片. 程序就能够提取出金融票据图片中的日期, 金额等信息和图片路径信息显示在屏幕上. 程序还设置了帮助按键,使用者通过帮助按钮获得帮助.由图可见票据的日期为 19 年 06 月 22 日(062219), 程序可以…

CMMI之需求管理

需求管理&#xff08;Requirement Management, RM&#xff09;的目的在客户与开发方之间建立对需求的共同理解&#xff0c;维护需求与其他工作成果的一致性&#xff0c;并控制需求的变更。需求管理过程域是SPP模型的重要组成部分。本规范阐述了需求管理过程域的三个主要规程&am…

低代码平台是技术开发的未来主流吗?

2022年9月27日16:49:21 这个事情我想了很久&#xff0c;最终的结论是&#xff1a;低代码平台只会一些领域平台的部分功能模块的标配&#xff0c;不会成为技术主流。 部分代表性例子&#xff1a; 1&#xff0c;低代码平台很早就有了&#xff0c;比如Visual Basic 6.0 ,delphi这些…

电脑重装系统后每次都要选择系统怎么办

电脑重装系统是件非十分平常的事情&#xff0c;当电脑出现故障或卡顿不能解决&#xff0c;即可采取重装系统来修复。不过&#xff0c;有些用户遇到系统重装后每次开机都要选择系统&#xff0c;影响到电脑正常使用&#xff0c;想要解决这个问题&#xff0c;只要关闭引导配置就可…

【pandas】15 pandas数据结构

【pandas】15 pandas数据结构 2023.1.13 总结来自https://mofanpy.com/tutorials/data-manipulation/pandas/ 包括pandas数据结构Series/DataFrame;数据选取分类查询等内容15.1 为什么需要pandas 前面讲了numpy,我们发现&#xff0c;numpy主要用途就是对同一类数据进行处理&a…

多节点Linux环境打造

目录 一、环境准备 1. CentOS镜像下载 2. VMware下载 二、 安装操作系统 1. 配置虚拟机 2. 安装CentOS操作系统 3. 网络配置 4. 多节点打造 5. 节点网络互通 6. 关闭防火墙服务 7. 修改默认主机名 8. 关闭 SELinux 服务 9. 安装常用软件 一、环境准备 1. CentOS镜…

电脑重装系统后键盘失灵解决方法步骤

手提电脑重装系统后键盘失灵怎么办呢?众所周知,联想小新Air 13 Pro保持经典的黑色外观,凭借坚固和可靠的特性得到了很多用户的认可。有网友发现联想小新Air 13 Pro手提电脑重装系统后键盘会失灵&#xff0c;那么小编把手提电脑重装系统后键盘失灵解决方法分享给大家。 工具/原…

Vue声明式导航 编程式导航、导航守卫、axios拦截器

一、声明式导航 & 编程式导航 1. 声明式导航&#xff1a;以超链接方式实现的页面跳转&#xff0c;就是声明式导航 < a href‘url’> 链接文本或图像 < /a >< router-link to‘url’ > 链接文本或图像 < /router-link >2. 编程式导航&#xff1a;通…

录屏软件哪个好?电脑录屏软件排行榜推荐

你是不是还在为选不到合适的录屏软件而苦恼&#xff1f;市面上录屏软件种类繁多&#xff0c;功能参差不齐确实不好选择。录屏软件哪个好&#xff1f;怎样才能找到适合自己的录屏软件&#xff1f;不用焦虑。今天小编给大家推荐3款电脑录屏软件排行榜前列的录屏软件&#xff0c;每…

day37【代码随想录】贪心算法之划分字母区间、合并区间、单调递增的数字、买卖股票的最佳时机含手续费、监控二叉树

文章目录前言一、划分字母区间&#xff08;力扣763&#xff09;二、合并区间&#xff08;力扣56&#xff09;三、单调递增的数字&#xff08;力扣738&#xff09;四、买卖股票的最佳时机含手续费&#xff08;力扣714&#xff09;五、监控二叉树&#xff08;力扣968&#xff09;…

1.14 IIC总线实验

一.IIC总线&#xff1a; 1.同步半双工串行总线&#xff0c;用于同一个开发板两个芯片之间的通信 2.有两根信号线&#xff0c;一根SDA,一根SCL 3.IIC总线需要外接两个上拉电阻&#xff0c;使空闲状态保持高电平 4.IIC总线支持多主机多从机模式&#xff0c;一般采用单主机多从…

STM32外部中断解析

文章目录前言一、外部中断是什么二、STM32F103的外部中断三、外部中断的中断号四、HAL库的外部中断初始化流程总结前言 本篇文章将带大家了解STM32F103的外部中断。 一、外部中断是什么 外部中断是单片机实时地处理外部事件的一种内部机制。当某种外部事件发生时&#xff0c…

数组名的意义

数组名只有单独放在sizeof内部以及放在&后才代表整个数组的地址。其余情况数组名都表示数组首元素地址。 之前我们说过用sizeof(a)计算的是整个数组的大小&#xff0c;现在我们知道其中的原因了。由于sizeof里的数组名a表示整个数组的地址&#xff0c;故sizeof(a)求的是整…

Android10以上系统Audio音频遇到播放无声时的分析方法

​商务合作 2023年招聘 2023年逆向分析资料汇总 推荐阅读 Android Audio音频系统 Android Audio音频系统之深入浅出 Android Framework/驱动/内核中高级工程师 ​Android10以上系统Audio音频遇到播放视频无声时的分析方法 干货|Android APP应用工程师转Framework工程师(…

51单片机存储结构

之前概要介绍了8151微控制器的结构&#xff08;也就是51单片机&#xff09;。相比微处理器&#xff0c;微控制器的区别之一是在一个芯片上有程序存储器(RAM)和数据存储器(RAM)。存储区是微控制器非常重要的内容。 本文就介绍一下8051的存储结构。包括存储器的组织、处理器对存储…

VTK-Tessellator Subdivision

前言&#xff1a;本博文主要研究Tessellator 的Subdivision&#xff0c;对vtk中的所有相关接口进行研究&#xff0c;并找出最优的解决方法。 GeometricObjects中vtkTessellatorFilter的应用实例 待研究对当前的Subdivision进行优化。 vtkTessellatorFilter 位置&#xff1a;…

Docker容器数据卷与数据卷容器

文章目录什么是容器数据卷使用数据卷使用 docker 安装 mysql匿名和具名挂载数据卷容器什么是容器数据卷 Docker理念回顾 将应用和运行的环境打包形成容器运行&#xff0c;运行可以伴随着容器&#xff0c;但是我们对于数据的要求&#xff0c;是希望能够 持久化的&#xff01; 就…