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

news2024/11/16 17:29:32

测试环境的搭建:

导入lombok:

不懂得小伙伴可移步这篇文章

新建实体类:

拿我们日常生活中最常见的举例:多个学生对应一个老师

对于学生这边而言,关联… 多个学生关联一个老师[多对一]
对于老师而言,集合…,一个老师,有很多学生[一对多]

student类:

package pojo;

import lombok.Data;

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

    //学生需要关联一个老师
    private Teacher teacher;
}

teacher类:

package pojo;
import lombok.Data;
@Data
public class Teacher {
    private int id;
    private String name;
}

数据库中创建关于老师和学生的表,并插入数据:

teacher表的创建和插入数据:

 create table teacher(id int not null,name varchar(30) default null,primary key(id));
insert into teacher(id,name) values(1,'秦老师');

student表的创建和插入数据:

create table student(id int not null,name varchar(30) default null,tid int default null,primary key(id),key fktid (tid),constraint fktid foreign key (tid) references teacher (id));
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);

建立Mapper.xml文件:

Mapper.xml文件创建方法如下,以**student_Mapper.xml**:为例

在这里插入图片描述

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.teacher_Mapper">

</mapper>

student_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.student_Mapper">

</mapper>

新建Mapper接口:

teacher_Mapper:

注:这里我使用的是注解对数据库进行操作,除了可以使用注解,还可以使用XML文件

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

public interface teacher_Mapper {
    @Select("select * from teacher where id =#{tid}")
    Teacher getTeacher(@Param("tid") int id);
}

student_Mapper:

注:这里我们只是进行环境的搭建,因此student_Mapper接口中并未写任何方法

package dao;

public interface student_Mapper {
}

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

说明:由于我们当前通过查询所有teacher的信息来检测配置环境是否正确,因此,这里绑定的为老师的接口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;

public class test{
    @Test
    public void getUserByLimit(){
        SqlSession sqlSession= mybatis_utils.getSqlSession();
        teacher_Mapper teacher_mapper=sqlSession.getMapper(dao.teacher_Mapper.class);
        Teacher teacher=teacher_mapper.getTeacher(1);
        System.out.println(teacher);
        sqlSession.close();
    }
}

输出部分结果如下:

在这里插入图片描述

测试环境搭建成功!

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

多对一处理:

处理内容:查询全体学生的信息,以及对应的老师的信息

按照查询嵌套处理:

下面的所有修改是建立在上述搭建好环境的基础上

在student_Mapper接口中编写方法:

package dao;
import pojo.Student;
import java.util.List;
public interface student_Mapper {
   public List<Student> getStudent();
}

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

<?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">
    <select id="getStudent" resultType="Student">
        select s.id,s.name,t.name from student s,teacher t where s.tid=t.id;
    </select>
</mapper>

在核心配置文件[mybatis-config.xml]中修改绑定的接口:

在这里插入图片描述

修改测试类中的所有部分代码:

在这里插入图片描述

从下图输出的结果中,我们发现teacher属性值为null,在之前的学习中,我们也出现过这种情况,我们知道原因是因为字段名和属性名不一致所导致的,我们的解决方法即为使用结果集映射进行处理,那么这里也可以这样解决吗?

在这里插入图片描述

答案是:不完全对!主要因为这里的teacher,并不是简单的字段类型,它是一个实体类,因此在进行结果集映射时,不能照搬普通字段进行结果集映射的方法

错误写法和正确写法对比如下:

错误写法错误的原因:

这里的SQL语句在数据库中进行查询是能够得到我们想要的结果,如下所示:

在这里插入图片描述

但为什么在这里关于teacher的信息是null呢?

原因是,在错误写法中,我们没有对其进行结果集映射,查看数据表中的字段和实体类中的字段,我们发现,数据表中是字段tid,而实体类中是teacher类,他们根本无法对应,因此查询为null

在这里插入图片描述

在这里插入图片描述

正确写法的思路:

既然要进行结果集映射,那么首先需要把resultType改为resultMap,根据我们之前的方法,使用result标签对字段和属性进行对应,但这里稍有不同,teacher是一个对象,并不是普通的字段。因此,你无法将其直接使用result标签,而应该association标签,property和column属性和普通的字段都是相同的写法,唯一的区别为后面的部分,javaType属性的值是指property属性对应的值的类型,select属性的值则表示通过select语句查询到教师的信息作为查询学生信息的第三列的值

在这里插入图片描述

将student_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">
    <select id="getStudent" resultMap="StudentTeacher">
        select * from student;
    </select>
    <resultMap id="StudentTeacher" type="Student">
        <result property="id" column="id"/>
        <result property="name" column="name"/>
        <!--复杂的属性,我么需要单独处理 对象:association 集合:collection-->
        <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
    </resultMap>
    <select id="getTeacher" resultType="Teacher">
        select * from teacher where id=#{id}
    </select>
</mapper>

测试输出的部分结果如下所示:此时teacher以一个对象的形式呈现出来

在这里插入图片描述

按照结果嵌套处理:

上述对于teacher属性的字段为null的处理,我们是采取了通过查询嵌套处理的方式,其实那种处理方式对于新手并不是很友好,下面我们所讲的这种按照结果嵌套查询的处理办法更加适合新手:

写法如下:

对比上面的按照查询嵌套处理的方式,下面的这种处理方式看起来逻辑更加清晰,因为select和resultMap是分开来写的,通过表连接的方式,将复杂属性的结果进行映射即可。

在这里插入图片描述

student_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">
    <!--按照结果嵌套处理-->
    <select id="getStudent" 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>

</mapper>

这样也能正确查询结果,这种方式更适合新手!

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

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

相关文章

BGP(边界网关路由协议)小实验

目录实验要求ospf协议启动关于BGP基本知识点BGP关系建立的配置BGP的宣告实验要求 如下实验拓扑&#xff0c;各个自治系统区域和网段已经标注 基本的ip配置&#xff0c;环回配置就不再展示。 要求&#xff1a;除了R5的环回外&#xff0c;其他环回均可以互相访问 ospf协议启动…

C语言进阶——自定义类型——位段、枚举、联合

结构体 目录 一. 位段 1.概念 2.位段的内存分配 3.位段的跨平台问题 4.位段的应用 二. 枚举 1.枚举类型的定义 2.枚举的优点 3.枚举的使用 三. 联合&#xff08;共用体&#xff09; 1.联合类型的定义 ​编辑 2.联合的特点 3. 联合大小的计算 一. 位段 1.…

Git 合并多条commit

文章目录修改前开始修改第一种方式: 命令行第二种方式: Android Studio遇到冲突的解决办法第一种&#xff1a;修改到底,干就完事了第二种&#xff1a;回滚吧&#xff0c;有点慌修改前 开始修改 第一种方式: 命令行 git rebase -i 01fc32484fb2d2229aa20 // 这里对应的是init的…

osg fbo(四),将颜色缓冲区图片中的牛通过shader变绿

osg fbo&#xff08;三&#xff09;中&#xff0c;把整个屏幕变绿了&#xff0c;因为是把shader添加到了颜色缓冲区图片上了。如果只想把牛变绿&#xff0c;就需要把shader添加到原始场景根中。 即 osg::ref_ptr<osg::StateSet> statset_SceneRoot sceneRoot->getOr…

一、Java框架之Spring配置文件开发

文章目录1. 基础概念1.1 Spring Framework1.2 核心概念产生背景IoC、Bean、DI2. 入门案例2.1 普通Maven项目2.2 IoC入门案例2.3 DI入门案例3. bean配置3.1 bean基础配置bean的基础配置bean的别名配置bean的作用范围3.2 bean实例化实例化方法1&#xff1a;构造方法实例化方法2&a…

Chrome浏览器http访问跨越问题与解决方法

一、Chromium 内核&#xff08;<93版本&#xff09;跨越问题解决方法 设置Chrome浏览器的 disable-web-security, 实现跨域访问后端的接口。这个参数可以降低chrome浏览器的安全性&#xff0c;禁用同源策略&#xff0c;利于开发人员本地调试。 解决办法&#xff1a; 新建一…

【区间合并】AcWing 803. 区间合并

803. 区间合并 文章目录题目描述输入格式&#xff1a;输出格式&#xff1a;数据范围输入样例输出样例方法&#xff1a;区间合并解题思路代码复杂度分析&#xff1a;题目描述 给定 nnn 个区间 [li,ri][l_i,r_i][li​,ri​]&#xff0c;要求合并所有有交集的区间。 注意如果在端…

按键精灵免字库本地识别OCR

按键精灵免字库识别—基于百度飞桨PaddleOCR的RapidOCR前言为什么为什么有大漠了还要使用其它OCR为什么要使用RapidOCR开发PaddleOCR介绍PaddleOCR使用衍生项目版——小白方案按键精灵post调用图片转base64方法转json方法post调用JVM版改为mavenOcrEngine路径idea Run配置网页版…

Hudi系列7:使用SparkSQL操作Hudi

文章目录一. SparkSQL连接Hudi1.1 Hive配置1.2 SparkSQL连接Hudi二. 创建表2.1 常规的建表2.2 CTAS三. 插入数据四. 查询数据五. 更新数据5.1 普通5.2 MergeInto六. 删除数据七. Insert Overwrite参考:一. SparkSQL连接Hudi 1.1 Hive配置 我们需要将Hive 的 metastore服务独立…

【Ubuntu18.04系统开启防火墙】

【Ubuntu18.04系统开启防火墙】1 查看防火墙状态2 开启防火墙3 关闭防火墙4 允许开启防火墙时&#xff0c;ssh连接和22端口许可4.1 允许tcp 22端口通过防火墙4.2 允许SSH服务4.3 防火墙规则重启4.4 验证端口号是否开启1 查看防火墙状态 sudo ufw status2 开启防火墙 sudo ufw…

如何重装windows10系统(超详细图文版)

目录1.&#xff08;制作装机盘&#xff09;准备好装机U盘2. (下载驱动软件&#xff09;(※这步很重要&#xff09;3.&#xff08;下载镜像&#xff09;准备好要安装的新操作系统镜像4.&#xff08;查询bios快捷键&#xff09;查询你的主板品牌&#xff0c;找到你主板品牌进入bi…

医用球囊和导管制造中的精确压力控制

摘要&#xff1a;在医用导管和球囊成型过程中对压力控制有非常严格要求&#xff0c;如高精度和宽量程的控制能力&#xff0c;需具备可编程、自动手动切换和外接压力传感器功能&#xff0c;还需具备可用于球囊泄漏、爆破和疲劳性能测试的多功能性。本文介绍了可满足这些要求的压…

连Pycharm都不知道怎么用,学什么Python?(doge))

python初始设置日常使用一、设置Python 解释器1.1 远程配置2、调整字体及其大小2.1 调整编辑器字体及其大小2.2 调整控制台的字体及其大小3、设置编码4、修改文件背景颜色5、设置Git 和Github5.1 配置git5.2 配置github5.3 下载仓库内容6 、新建.py文件时默认添加信息7、恢复代…

[ 环境搭建篇 ] 安装 java 环境并配置环境变量(附 JDK1.8 安装包)

&#x1f36c; 博主介绍 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 _PowerShell &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 &#x1f389;点赞➕评论➕收藏 养成习…

Demo演示:ARM+FPGA主流嵌入式架构板卡-HDMI显示摄像画面

各位工程师小伙伴们&#xff0c;大家好&#xff0c;ARMFPGA 作为一种主流的嵌入式系统的处理架构。相对于单纯的的ARM开发或单纯的FPGA开发&#xff0c;ARM加FPGA能够带来功耗、性能、成本等组合优势。 米尔新推出的MYD-JX8MMXA7开发板基于ARMFPGA架构&#xff0c;集成i.MX 8M…

多线程理解之3

1.怎么解决多线程并发访问临界资源的产生的问题&#xff1f; 用锁 pthread_mutex_t mtx解决。 2.mtx锁的作用具体是什么&#xff1f; 先把临界资源锁起来&#xff0c;再把它打开&#xff0c;这样一来&#xff0c;多个执行流想要同时执行临界资源就不可以了&#xff0c;只能一个…

[C++]string的使用及模拟实现

&#x1f941;作者&#xff1a; 华丞臧 &#x1f4d5;​​​​专栏&#xff1a;【C】 各位读者老爷如果觉得博主写的不错&#xff0c;请诸位多多支持(点赞收藏关注)。如果有错误的地方&#xff0c;欢迎在评论区指出。 推荐一款刷题网站 &#x1f449;LeetCode 文章目录一、stri…

Android Compose——Paging3

Paging3效果视频简述HiltRetrofit访问接口网络实例PagingSourceViewModelView效果视频 简述 本Demo采用HiltRetrofitPaging3完成&#xff0c;主要为了演示paging3分页功能的使用&#xff0c;下列为Demo所需要的相关依赖 //retrofitimplementation com.squareup.retrofit2:retr…

多线程之内功精修

文章目录一、常见的锁策略&#xff08;一&#xff09;悲观锁和乐观锁&#xff08;二&#xff09;读写锁和互斥锁&#xff08;三&#xff09;重量级锁和轻量级锁&#xff08;四&#xff09;挂起等待锁和自旋锁&#xff08;五&#xff09;公平锁和非公平锁&#xff08;六&#xf…

nerdctl容器管理工具

nerdctl容器管理工具nerdctl简介nerdctl的两个版本安装nerdctl1.配置nerdctl自动补全2.将nerdctl设别名为dockernerdctl使用方法1、运行/计入容器2、容器管理3、镜像管理4、镜像构建nerdctl简介 k8s1.22版本及以上强制安装containerd,要求卸载Docker. 虽然Docker能干的事Conta…