MyBatis的关联映射

前言

    在实际开发中,对数据库的操作通常会涉及多张表,MyBatis提供了关联映射,这些关联映射可以很好地处理表与表,对象与对象之间的的关联关系。

一对一查询

步骤:

  1. 先确定表的一对一关系
  2. 确定好实体类,添加关联对象
  3. 使用resultMap定义好输出参数
  4. 编写sql语句
  5. 测试

    在MyBatis中,通过<association>元素来处理一对一的关联关系。<association>元素中的属性如下:

属性说明
property用于指定映射到的实体类对象的属性,与表字段一一对应
column用于指定表中对应的字段
javaType用于指定映射到实体对象的属性的类型
jdbcType用于指定数据库中对应字段的类型
fetchType用于指定关联查询时是否延迟加载。fetchType有lazy和eager两个属性值,默认为lazy延迟加载
select用于引入嵌套查询的SQL语句,该属性用于关联映射的嵌套查询
autoMapping用于指定是否自动映射
typeHandler用于指定一个类型处理器
    <resultMap id="oneByOne" type="com.cc.User">
        <id column="id" property="id"/>
        <result column="name" property="name"/>
        <result column="gender" property="gender"/>
        <result column="age" property="age"/>
        <result column="address" property="address"/>
        <result column="email" property="email"/>
        <result column="qq" property="qq"/>
        <association property="login" javaType="com.cc.Login">
            <id column="id" property="id"/>
            <result column="username" property="username"/>
            <result column="password" property="password"/>
        </association>
    </resultMap>

    <select id="findPassword" resultMap="oneByOne">
        select u.*,l.* from tb_userinfo u,tb_login l where u.name=l.username;
    </select>

   使用resultMap定义结果映射集,其中id标签用于映射数据库表中的主键字段,column为数据库的列名,property为java类的属性名。result用于映射普通字段。

    association标签用于映射关联对象的信息。property为关联对象的属性名,javaType为关联对象的Java类路径

一对多查询 

    在MyBatis中,通过<collection>元素来处理一对多关联关系。<collection>大多与<association>元素相同,还包含一个特殊属性ofType与javaType属性相对应,它用于指定实体类对象中集合类属性所包含的元素的类型。


示例:

    通过tb_userinfo表中的name值与tb_login中的username关联查询出两张表中的数据:

    将userinfo表与login两张表设计成两个实体类,并将login作为属性加入到userinfo中(也可以反过来):

public class User {
    private String id;
    private String name;
    private String gender;
    private int age;
    private String address;
    private String email;
    private String qq;
    private Login login;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public Login getLogin() {
        return login;
    }

    public void setLogin(Login login) {
        this.login = login;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getQq() {
        return qq;
    }

    public void setQq(String qq) {
        this.qq = qq;
    }

    public User(String name, String gender, int age, String address, String email, String qq) {
        this.name = name;
        this.gender = gender;
        this.age = age;
        this.address = address;
        this.email = email;
        this.qq = qq;
    }

    public User() {
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                ", age=" + age +
                ", address='" + address + '\'' +
                ", email='" + email + '\'' +
                ", qq='" + qq + '\'' +
                ", login=" + login +
                '}';
    }
}





public class Login {
    private Integer id;
    private String username;
    private String password;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
    public Login(){

    }

    public Login(String password, String username) {
        this.password = password;
        this.username = username;
    }

    @Override
    public String toString() {
        return "Login{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

    <resultMap id="order" type="com.cc.User">
        <id column="id" property="id"/>
        <result column="name" property="name"/>
        <result column="gender" property="gender"/>
        <result column="age" property="age"/>
        <result column="address" property="address"/>
        <result column="email" property="email"/>
        <result column="qq" property="qq"/>
        <collection property="login" ofType="com.cc.Login">
            <id column="id" property="id"/>
            <result column="username" property="username"/>
            <result column="password" property="password"/>
        </collection>
    </resultMap>

    <select id="findPassword" resultMap="order">
        select u.*,l.* from tb_userinfo u,tb_login l where u.name=l.username;
    </select>

测试: 

        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<User> u = userMapper.findPassword();
        for (User user:u){
            System.out.println(user);
        }

    在使用MyBatis嵌套查询进行MyBatis关联映射查询时,使用MyBatis的延迟加载在一定程度上可以降低运行消耗并提高查询效率。MyBatis默认没有开启延迟加载,需要在核心配置文件mybatis.xml中的setting元素内进行配置。

        <setting name="lazyLoadingEnabled" value="true"/>
        <setting name="aggressiveLazyLoading" value="false"/>

多对多查询

    在数据库中,多对多的关联关系通常要使用一个中间表来维护。

    例如,要查询每个员工的职位,根据employee的id值在emp_posi找到对应的pid,再根据pid查找position职位的名称,如下图所示:

映射思路:

将position信息映射到employee中

在position添加属性List<EP> eps

mapper配置如下: 

    <resultMap id="map" type="com.cc.entity.Employee">
        <id property="id" column="id"/>
        <result property="name" column="name"/>
        <result property="age" column="age"/>
        <result property="position" column="position"/>
        <collection property="positions" ofType="com.cc.entity.Position">
            <id property="id" column="id"/>
            <result property="name" column="name"/>
            <collection property="eps" ofType="com.cc.entity.EP">
                <id property="id" column="id"/>
                <result property="eId" column="emp_id"/>
                <result property="pId" column="posi_id"/>
            </collection>
        </collection>
    </resultMap>
    <select id="selectPosi" resultMap="map">
        select e.*,p.*,ep.*
            from employee e,position p,emp_posi ep
        where e.id=ep.emp_id and ep.posi_id=p.id;
    </select>

 查询结果如下:

发现查询出的职位错查成employee中的name值。出现该错误的原因是employee和position表使用了相同的列名name,解决方法就是给这些字段起别名

 

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

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

相关文章

利用Git和wget批量下载网页数据

一、Git的下载&#xff08;参考文章&#xff09; 二. wget下载&#xff08;网上很多链接&#xff09; 三、git和wget结合使用 1.先建立一个文本&#xff0c;将代码写入文本&#xff08;代码如下&#xff09;&#xff0c;将txt后缀改为sh&#xff08;download_ssebop.sh&#xf…

deepseek助力运维和监控自动化

将DeepSeek与Agent、工作流及Agent编排技术结合&#xff0c;可实现IT运维与监控的智能化闭环管理。以下是具体应用框架和场景示例&#xff1a; 一、智能Agent体系设计 多模态感知Agent 日志解析Agent&#xff1a;基于DeepSeek的NLP能力&#xff0c;实时解析系统日志中的语义&a…

从零开始实现机器臂仿真(UR5)

1. UR5软件配置 # 安装 MoveIt! 依赖 sudo apt install ros-humble-moveit ros-humble-tf2-ros ros-humble-moveit-setup-assistant ros-humble-gazebo-ros-pkgs # 安装 UR 官方 ROS2 驱动 sudo apt update sudo apt install ros-humble-ur-robot-driver ros-humble-ur-descri…

h5 IOS端渐变的兼容问题 渐变实现弧形效果

IOS端使用渐变的时候有兼容问题 以下是问题效果&#xff0c;图中黑色部分期望的效果应该是白色的。但是ios端是下面的样子…… 安卓pc 支持&#xff1a; background-image: radial-gradient(circle 40rpx at 100% 0, #f3630c 40rpx, rgb(255, 255, 255) 50%);安卓pc ios支持…

文件上传漏洞与phpcms漏洞安全分析

目录 1. 文件上传漏洞简介 2. 文件上传漏洞的危害 3. 文件上传漏洞的触发条件 1. 文件必须能被服务器解析执行 2. 上传目录必须支持代码执行 3. 需要能访问上传的文件 4. 例外情况&#xff1a;非脚本文件也可能被执行 4. 常见的攻击手法 4.1 直接上传恶意文件 4.2 文件…

DeepSeek 助力 Vue3 开发:打造丝滑的时间选择器(Time Picker)

前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦 💕 目录 DeepSeek 助力 Vue3 开发:打造丝滑的时间选择器(Time Picker)📚前言📚页面效果📚指令输入…

「多开浏览器」颜值升级之「消灭堆叠的窗口」(二)

01 传统指纹浏览器的架构 传统指纹浏览器&#xff08;也称为多用户浏览器或反检测浏览器&#xff09;是一种用于模拟多个独立用户环境的技术工具&#xff0c;主要用于网络爬虫、广告验证、社交媒体管理等场景。其核心目标是通过模拟不同的浏览器指纹&#xff08;Browser Finge…

IndexError: index 0 is out of bounds for axis 1 with size 0

IndexError: index 0 is out of bounds for axis 1 with size 0 欢迎来到英杰社区&#xff0c;这里是博主英杰https://bbs.csdn.net/topics/617804998 报错原因 数组或数据结构为空 如果数组或 DataFrame 在指定的维度上没有任何元素&#xff08;例如&#xff0c;没有列&#x…

本地部署阿里万象2.1文生视频模型(Wan2.1-T2V)完全指南

在生成式AI技术爆发式发展的今天,阿里云开源的万象2.1(Wan2.1)视频生成模型,为创作者提供了从文字/图像到高清视频的一站式解决方案。本文针对消费级显卡用户,以RTX 4060 Ti 16G为例,详解本地部署全流程与性能调优方案,涵盖环境配置、多模型选择策略、显存优化技巧及实战…

[Python学习日记-85] 并发编程之多进程 —— Process 类、join 方法、僵尸进程与孤儿进程

[Python学习日记-85] 并发编程之多进程 —— Process 类、join 方法、僵尸进程与孤儿进程 简介 multiprocessing 模块 Process 类 僵尸进程与孤儿进程 简介 在前面的进程理论的介绍当中我们已经介绍了进程的概念、并发与并行的区别以及进程并发的实现理论&#xff0c;这些都…

飞书考勤Excel导入到自己系统

此篇主要用于记录Excel一行中&#xff0c;单条数据的日期拿取&#xff0c;并判断上下班打卡情况。代码可能满足不了大部分需求&#xff0c;目前只够本公司用&#xff0c;如果需要&#xff0c;可以参考。 需要把飞书月度汇总的考勤表导入系统中可以参考下。 下图为需要获取的年…

Python项目】基于Python的图像去雾算法研究和系统实现

Python项目】基于Python的图像去雾算法研究和系统实现 技术简介&#xff1a;采用Python技术、MYSQL数据库等实现。 系统简介&#xff1a;图像去雾系统主要是基于暗通道先验和逆深度估计技术的去雾算法&#xff0c;系统功能模块分为&#xff08;1&#xff09;图像上传模块&…

游戏引擎学习第135天

仓库:https://gitee.com/mrxiao_com/2d_game_3 回顾 game_asset.cpp 的创建 在开发过程中&#xff0c;不使用任何现成的游戏引擎或第三方库&#xff0c;而是直接基于 Windows 进行开发&#xff0c;因为 Windows 目前仍然是游戏的标准平台&#xff0c;因此首先在这个环境中进行…

【Linux】冯诺依曼体系结构-操作系统

一.冯诺依曼体系结构 我们所使用的计算机&#xff0c;如笔记本等都是按照冯诺依曼来设计的&#xff1a; 截止目前&#xff0c;我们所知道的计算机都是由一个一个的硬件组装起来的&#xff0c;这些硬件又由于功能的不同被分为了输入设备&#xff0c;输出设备&#xff0c;存储器…

[liorf_localization_imuPreintegration-2] process has died

使用liorf&#xff0c;编译没报错&#xff0c;但是roslaunch报错如下&#xff1a; 解决方法&#xff1a; step1: 如果你之前没有安装 GTSAM&#xff0c;可以尝试安装它 step2: 检查是否缺少依赖库 ldd /home/zz/1210/devel/lib/liorf_localization/liorf_localization_imuPr…

模块11_面向对象

文章目录 模块11_面向对象模块十回顾&&模块十一重点 第一章.接口1.接口的介绍2.接口的定义以及使用3.接口中的成员3.1抽象方法3.2默认方法3.3静态方法3.4成员变量3.4成员变量 4.接口的特点5.接口和抽象类的区别 第二章.多态1.多态的介绍2.多态的基本使用3.多态的条件下…

常见webshell工具的流量特征

1、蚁剑 1.1、蚁剑webshell静态特征 蚁剑中php使用assert、eval执行&#xff1b;asp只有eval执行&#xff1b;在jsp使用的是Java类加载&#xff08;ClassLoader&#xff09;&#xff0c;同时会带有base64编码解码等字符特征。 1.2、蚁剑webshell动态特征 查看流量分析会发现…

03标准IO接口

一、系统与标准IO的区别 相同点:系统IO与标准IO都可以操作linux系统下的文件。 ⭐不同点: 系统IO&#xff1a;打开文件得到的是一个整数&#xff0c;称为文件描述符。 标准IO&#xff1a;打开文件得到的是一个指针&#xff0c;称为文件指针。系统IO&#xff1a;可以访问linux…

Axure高保真Element框架元件库

点击下载《Axure高保真Element框架元件库》 原型效果&#xff1a;https://axhub.im/ax9/9da2109b9c68749a/#g1 摘要 本文详细阐述了在 Axure 环境下打造的一套高度还原 Element 框架的组件元件集。通过对 Element 框架组件的深入剖析&#xff0c;结合 Axure 的强大功能&#…

【Linux】进程信号——信号保存和信号捕捉

文章目录 信号保存信号相关的概念信号是如何保存的呢&#xff1f;有关信号保存的系统调用sigprocmask信号的增删查改查看pending表验证接口 信号捕捉用户态与内核态信号捕捉流程 总结 信号保存 信号相关的概念 信号递达&#xff1a;指 操作系统 将一个信号&#xff08;Signal…