Mybatis高级查询-一对一查询

news2024/10/10 22:59:47
表介绍和表关系说明
新建以下4张表
tb_user:用户表
tb_order:订单表
tb_item:商品表
tb_orderdetail:订单详情表

【表关系】

1.tb_user和 tb_order表关系
    tb_user  《==》  tb_order:一对多, 一个人可以下多个订单
    tb_order 《==》 tb_user:一对一,一个订单只能属于一个人
    结论:tb_user和tb_order属于一对多的关系,需要将一方tb_user的主键作为多方tb_order的外键维护关系
2.tb_order 和 tb_item 表关系
    tb_order 《==》 tb_item :一个订单可以有多个商品
    tb_item 《==》 tb_order:一个商品可以在多个订单上
    结论:tb_order和tb_item属于多对多的关系,需要创建中间表tb_orderdetail维护两个表的关系,并且将两张表    的主键作为中间表的外键

一对一查询

需求:通过订单编号20140921003查询出订单信息,并查询出下单人信息。

【实现:关联查询】

【目标】使用多表关联查询,完成根据订单号查询订单信息和下单人信息(订单号:20140921003)

【分析】

一个订单编号对应一个订单,一个订单只能属于一个人。所以上述需求实现是一对一的实现。

【步骤】

1、首先,编写接口方法。编写SQL语句;
2、第二步:分析SQL,封装数据(关联对象);
3、处理多表之间的数据封装(数据库字段名---》实体类的属性名之间的映射)

【实现】

第一步:需求分析

编写多表关联查询SQL,根据订单号查询订单信息下单人信息;

查询语句以及查询结果:

    #方式一:分步查询
    #第一步:根据order_number查询订单信息;
    SELECT * FROM tb_order WHERE order_number = '20140921003';
    #第二步:根据订单信息中的user_id查询出下单人的信息;
    SELECT * FROM tb_user WHERE id = 1;

  #方式二:多表关联查询,内连接
    SELECT * FROM tb_order tbo inner join tb_user tbu on tbo.user_id = tbu.id where 
  tbo.order_number='20140921003'
    #多表数据封装问题:
    #关联对象封装数据(在Order中引用User)
第二步:添加关联

修改Order:

在Order类中,添加关联对象User,并添加getter和setter方法;

package com.itheima.sh.pojo;
/**
 * 订单表
 * 
 */
public class Order {
    private Integer id;
    private String orderNumber;
    //关联User对象
    private User user;
    public Integer getId() {
        return id;
    }

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

    public String getOrderNumber() {
        return orderNumber;
    }
    public void setOrderNumber(String orderNumber) {
        this.orderNumber = orderNumber;
    }
    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }
    @Override
    public String toString() {
        return "Order{" +
        "id=" + id +
        ", orderNumber='" + orderNumber + '\'' +
        ", user=" + user +
        '}';
    }
}
第三步:添加方法

编写OrderMapper接口

public interface OrderMapper {
    /**
     * 根据订单号查询订单及下单人的信息:方式二
     * @param orderNumber
     * @return
     */
    Order queryOrderAndUserByOrderNumber2(@Param("orderNumber")String orderNumber);
}
第四步:编写SQL

在OrderMapper.xml中编写对应的SQL,并将OrderMapper.xml加入到mybatis-config.xml全局配置中;

【OrderMapper.xml代码;】

说明:

association:配置关联对象(User)的映射关系
 <association property="user" javaType="User" autoMapping="true">

  </association>

    属性:
        property:关联对象在主表实体类中的属性名;property="user" 表示在Order类中的引用的User类的对象           成员变量名
        javaType:关联对象的类型;javaType="User" 表示引用的user对象属于User类型

-----------------------------------------------------------------------------------------
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--
映射文件
namespace 指定接口的类全名
-->
<mapper namespace="com.itheima.sh.dao.OrderMapper">
    <!--
        1.autoMapping="true" 表示只需要给当前表的id然后自动映射当前表的其他列值到
        对应实体类的属性中,这属于偷懒行为,开发中我们最好都书写出来
        2.id标签表示id的映射关系
        3.result标签表示其他列和pojo类的属性映射关系
        4.一对一映射关系使用子标签association来表示引用的另一个pojo类的对象
    -->
    <resultMap id="orderAndUserResultRelative" type="Order" autoMapping="true">
        <!--主表主键-->
        <id column="id" property="id"/>
        <!--关联关系-->
        <!--
            1.property="user" 表示在Order类中的引用的User类的对象成员变量名
            2.javaType="User" 表示引用的user对象属于User类型
        -->
        <association property="user" javaType="User" autoMapping="true">
            <!--从表主键-->
            <id column="id" property="id"/>
            <!--<result column="user_name" property="userName"/>-->
        </association>

    </resultMap>


    <!--多表关联查询:一对一-->
    <select id="queryOrderAndUserByOrderNumber2" resultMap="orderAndUserResultRelative">
        SELECT
            *
        FROM
            tb_order tbo
            INNER JOIN tb_user tbu ON tbo.user_id = tbu.id
        WHERE
            tbo.order_number = #{orderNumber}
    </select>

</mapper>

说明:

1、由于queryOrderAndUserByOrderNumber2查询的结果Order对象中需要封装User信息,所以返回值不能够再使用单纯的resultType来操作;

2、定义resultMap进行关联查询的配置,其中:
    属性:
        id:标识这个resultMap;
        type:返回的结果类型
        autoMapping="true": 表示只需要给当前表的id然后自动映射当前表的其他列值到对应实体类的属性中,这          属于偷懒行为,开发中我们最好都书写出来
    子元素:
        id:主表主键映射
        result:主表普通字段的映射
        association:关联对象的映射配置

3、association:配置关联对象(User)的映射关系
    属性:
        property:关联对象在主表实体类中的属性名;property="user" 表示在Order类中的引用的User类的对象           成员变量名
        javaType:关联对象的类型;javaType="User" 表示引用的user对象属于User类型
第五步:测试
package com.itheima.sh.test;

import com.itheima.sh.dao.OrderMapper;
import com.itheima.sh.dao.UserMapper;
import com.itheima.sh.pojo.Order;
import com.itheima.sh.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.BeforeClass;
import org.junit.Test;
import java.io.InputStream;
public class MybatisTest02 {
    private static OrderMapper mapper = null;
    @BeforeClass
    public static void beforeClass() throws Exception {
        //1.构建SessionFactory
        String resouce = "mybatis-config.xml";
        InputStream is = Resources.getResourceAsStream(resouce);
        SqlSessionFactory build = new SqlSessionFactoryBuilder().build(is);
        //2.获取session
        SqlSession sqlSession = build.openSession(true);
        //3.获取接口对象
        mapper = sqlSession.getMapper(OrderMapper.class);
    }
    @Test
    public void selectById() {
        Order order = mapper.queryOrderAndUserByOrderNumber2("20140921003");
        System.out.println("order = " + order);
    }
}

【测试结果】

注意事项

通过上述测试结果,我们发现User的id是错误的,不是3,正确结果是1:

因为tb_user表的主键是id,tb_order的主键也是id。查询的结果中有两列相同的id字段。在将查询结果封装到实体类的过程中就会封装错误。

注意:user表查询的是id不是id1,由于SQLyog图形化界面显示的原因。可以在cmd窗口查看结果:

【解决方案】

1、建议将所要查询的所有字段显示地写出来;
2、将多表关联查询结果中,相同的字段名取不同的别名;

resultMap中应该如下配置:

【正确结果】

【小结】
一对一关联查询:
1、需要在Order实体类中关联User对象;最终将数据封装到Order中;
2、在OrderMapper.xml文件中书写关联语句并配置关系;
3、关联关系配置:
        <resultMap id="orderAndUserResultRelative" type="Order" autoMapping="true">
            <!--主表主键-->
            <id column="oid" property="id"/>
            <!--关联关系-->
            <association property="user" javaType="User" autoMapping="true">
                <!--从表主键-->
                <id column="uid" property="id"/>
            </association>

        </resultMap>

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

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

相关文章

第 4 章 Spring IoC容器之BeanFactory

Spring 的 IoC 容器是一个提供 IoC 支持的轻量级容器&#xff0c;除了基本的 IoC 支持&#xff0c;它作为轻量级容器还提供了 IoC 之外的支持。 Spring 提供了两种容器类型&#xff1a;BeanFactory 和 ApplicationContext&#xff1a; BeanFactory&#xff0c;基础类型 IoC 容…

布隆过滤器(Bloom Filter)详解

一、引言 在处理大量数据的场景中&#xff0c;我们经常会遇到判断一个元素是否在某个集合中的问题。传统的方法可能是使用 HashMap 等集合将数据保存起来&#xff0c;然后进行比较确定&#xff0c;但在元素很多的情况下&#xff0c;这种方式会非常浪费空间&#xff0c;检索速度…

dayu_widgets-简介

前言: 越来越多的人开始使用python来做GUI程序&#xff0c;市面上却很少有好的UI控件。即使有也是走的商业收费协议&#xff0c;不敢使用&#xff0c;一个不小心就收到法律传票。 一、原始开源项目: 偶然在GitHub上发现了这个博主的开源项目。https://github.com/phenom-films…

Fiddler配合wireshark解密ssl

环境&#xff1a; win11&#xff08;wireshark&#xff09;--虚拟机win7&#xff08;Fiddler&#xff09;---虚拟机win7&#xff08;HTTPS站点&#xff09; 软件安装问题&#xff1a; 需要.net环境&#xff0c;NDP461-KB3102436-x86-x64-AllOS-ENU.exe。 安装fiddler后安装下…

Pytest测试用例生命周期管理-Fixture

1、Fixture 用法 Fixture 特点及优势 1&#xff64;命令灵活&#xff1a;对于 setup,teardown,可以不起这两个名字2&#xff64;数据共享&#xff1a;在 conftest.py 配置⾥写⽅法可以实现数据共享&#xff0c;不需要 import 导⼊。可以跨⽂件共享3&#xff64;scope 的层次及…

从FastBEV来学习如何做PTQ以及量化

0. 简介 对于深度学习而言&#xff0c;通过模型加速来嵌入进C是非常有意义的&#xff0c;因为本身训练出来的pt文件其实效率比较低下&#xff0c;在讲完BEVDET后&#xff0c;这里我们将以CUDA-FastBEV作为例子&#xff0c;来向读者展示如何去跑CUDA版本的Fast-BEV&#xff0c;…

动态规划算法-路径问题——LCR.166.珠宝的最高价值

1.题目解析 题目来源&#xff1a;LCR.166珠宝的最高价值 原名&#xff1a;剑指offer47.礼物的最大价值 测试用例 2.算法原理 1.状态表示 创建dp表&#xff0c;dp[i][j]表示从最左上角到该目标位置的最大礼物值&#xff0c;代表dp[i][j]的状态 2.状态转移方程 目标位置的最大礼物…

SOMEIP_ETS_178: Subscribe_using_wrong_SOMEIP_MessageID

测试目的&#xff1a; 验证DUT能够拒绝一个SOME/IP头部使用错误消息ID进行服务发现的SubscribeEventgroup消息&#xff0c;并以SubscribeEventgroupNAck作为响应。 描述 本测试用例旨在确保DUT遵循SOME/IP协议&#xff0c;当接收到一个使用错误消息ID的服务发现SubscribeEve…

【livox】雷达初始化成功,但没有点云(已解决)

设备&#xff1a; 一台orin&#xff08;arm&#xff09; 接网线&#xff0c;本地ip&#xff1a;192.168.1.6 livox雷达&#xff1a;HAP 雷达初始ip&#xff1a;192.168.1.100 实物如下图&#xff1a; 然后 安装 livox_SDK 和 驱动 livox_ros_driver2 参考 【Livox】安…

通信界的5G-A/F5G-A新技术,你知道多少?

2024年已经过去了一大半&#xff0c;风起云涌的AI浪潮&#xff0c;又发生了不小的变化。 一方面&#xff0c;AI大模型的复杂度不断提升&#xff0c;模型参数持续增加&#xff0c;智算集群的规模也随之增加。万卡级、十万卡级集群&#xff0c;已经逐渐成为训练标配。这对智算网络…

心觉:开发潜意识的详细流程和步骤是什么

Hi&#xff0c;我是心觉&#xff0c;与你一起玩转潜意识、脑波音乐和吸引力法则&#xff0c;轻松掌控自己的人生&#xff01; 挑战每日一省写作195/1000天 最近领教了一下潜意识的力量和吸引力法则 我想要一张可以放在榻榻米壁柜上的迷你型的电动升降桌&#xff0c;桌面60cm…

《花100块做个摸鱼小网站! 》第七篇—谁访问了我们的网站?

⭐️基础链接导航⭐️ 服务器 → ☁️ 阿里云活动地址 看样例 → &#x1f41f; 摸鱼小网站地址 学代码 → &#x1f4bb; 源码库地址 一、前言 大家好呀&#xff0c;我是summo&#xff0c;最近发生了些事情(被裁员了&#xff0c;在找工作中)导致断更了&#xff0c;非常抱歉。…

基于SpringBoot+Vue+Uniapp汽车保养系统小程序的设计与实现

详细视频演示 请联系我获取更详细的演示视频 项目运行截图 技术框架 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的开源框架。它采用约定大于配置的理念&#xff0c;提供了一套默认的配置&#xff0c;让开发者可以更专注于业务逻辑而…

写一个代码:打印100~200之间的素数

我们要输出100-200之间的素数&#xff0c;首先我们先得输出100-200之间的数字&#xff0c;一般用于遍历循环的数字要用到for循环&#xff0c;同时在输出的100~200之间的数字进行判断是不是素数&#xff0c;我们知道素数的判断条件在于当一个数字从1开始到自己本身的时候&#x…

Android Framework AMS(03)AMS关键类解读

该系列文章总纲链接&#xff1a;专题总纲目录 Android Framework 总纲 本章关键点总结 & 说明&#xff1a; 说明&#xff1a;本章节主要涉AMS的关键类及其设计理念的解读&#xff0c;主要关注图中下方AMS关键类解读部分即可。这么做的目的是为了后面章节分析AMS时更容易理解…

基于SpringBoot+Vue+Uniapp家具购物小程序的设计与实现

详细视频演示 请联系我获取更详细的演示视频 项目运行截图 技术框架 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的开源框架。它采用约定大于配置的理念&#xff0c;提供了一套默认的配置&#xff0c;让开发者可以更专注于业务逻辑而…

MySql外键约束

数据库约束 对储存数据的约束&#xff0c;确保储存数据的准确性 not null&#xff08;非空约束&#xff09; 该行不能不存储值&#xff0c;null也不能default 默认约束当没有插入值时&#xff0c;该列就默认插入default给的值unique 唯一约束这个行的数据是唯一的prim…

Spark常用RDD算子:transformation转换算子以及action触发算子

文章目录 1. 算子&#xff08;方法&#xff09;介绍2. 常用transformation算子2.1 map 2.2 flatMap2.3 filter2.4 distinct2.6 groupBy2.7 sortBy()2.8 k-v数据[(k,v),(k1,v1)] 3. 常用action算子 1. 算子&#xff08;方法&#xff09;介绍 rdd中封装了各种算子方便进行计算&a…

传感器模块编程实践(四)舵机+MPU6050陀螺仪模块融合云台模型

文章目录 一.概要二.实验模型原理1.硬件连接原理框图2.控制原理 三.实验模型控制流程四.云台模型程序五.实验效果视频六.小结 一.概要 云台主要用来固定摄像头。准确地说&#xff0c;云台是一种可以多角度调节的支撑设备&#xff0c;类似于人的脖子可以支撑着脑袋&#xff0c;…

java随机生成数学算式

生成随机数学算式可谓是计算机领域的一个经典的问题, 本文使用JFrame,JButton,JTextField等java图形化工具,生成一个可以随机切换题目,可以实现计时功能的一个图形化界面 源代码展示 randomMath类 package login;import javax.swing.*; import java.awt.*; import java.awt.e…