Mybatis之多表查询

news2025/5/24 3:06:38

目录

一、简介

1、使用嵌套查询:

2、使用多个 SQL 语句:

3、使用关联查询:

4、使用自定义映射查询:

二、业务场景

三、示例

1、一对一查询

2、一对多查询


一、简介

MyBatis 是一个优秀的持久层框架,它提供了强大的支持来执行数据库操作,包括多表查询。多表查询是指从多个数据库表中检索数据的过程,这在实际的应用中非常常见。MyBatis 提供了多种方法来执行多表查询,以下是一些常见的技术和方法:

1、使用嵌套查询:

这是最基本的多表查询方法,通过在 SQL 语句中嵌套子查询来联合多个表的数据。例如,你可以在 SELECT 语句中使用子查询来从一个表中获取数据,然后再将其用于主查询中。这种方法在某些简单情况下是有效的,但对于复杂的多表查询可能会变得冗长和难以维护。

2、使用多个 SQL 语句

在 MyBatis 中,你可以编写多个独立的 SQL 语句,每个语句都从一个表中检索数据,然后在 Java 代码中将这些数据组合起来。这通常需要在 Java 代码中手动执行每个查询并进行数据处理,但对于一些复杂的多表查询情况可能更加灵活。

3、使用关联查询:

 MyBatis 支持使用关联查询来执行多表查询,特别是在映射文件中配置了表之间的关联关系。通过在 Mapper XML 文件中配置 association 或 collection 来表示表之间的关联关系,MyBatis 可以自动根据关系从多个表中检索数据并构造结果对象。

4、使用自定义映射查询

有时候,多表查询的结果可能不适合于一个实体类,这时你可以使用自定义映射查询来将结果映射到一个 Map 或者其他自定义的数据结构中,以适应查询的需要。

二、业务场景

模拟的业务场景为订单与用户的关系,可以是一对一、一对多。

比如,一个用户有多个订单,一个订单只有一个用户。

还有就是用户与角色的关系,多个用户拥有多个角色,一个角色可以被多个用户拥有,一个用户可以拥有多个角色。

三、示例

1、一对一查询

案例:查询所有订单信息,关联查询下单用户信息。 注意:因为一个订单信息只会是一个人下的订单,所以从查询订单信息出发关联查询用户信息为一对一查询。如果从用户信息出发查询用户下的订单信息则为一对多查询,因为一个用户可以下多个订单。

一对一查询的需求:查询一个订单,与此同时查询出该订单所属的用户

数据库:

对应的SQL语句:

select o.id,o.ordername,o.ordercount,s.studentname,s.address from orders o,student s where o.student_id = s.id

用户表student

public class Student {
    private int id;
    private String studentName;
    private String gender;
    private String address;
    private String email;
    private String remark;
   

    public Student() {
    }

    public Student( String studentName, String gender, String address, String email, String remark) {

        this.studentName = studentName;
        this.gender = gender;
        this.address = address;
        this.email = email;
        this.remark = remark;
    }

    public int getId() {
        return id;
    }

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

    public String getStudentName() {
        return studentName;
    }

    public void setStudentName(String studentName) {
        this.studentName = studentName;
    }

    public String getGender() {
        return gender;
    }

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

    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 getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }


    }
}

订单表order

public class Order {
    private int id;
    private String ordername;
    private int ordercount;
    private Student student;
   

  

    public int getId() {
        return id;
    }

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

    public String getOrdername() {
        return ordername;
    }

    public void setOrdername(String ordername) {
        this.ordername = ordername;
    }

    public int getOrdercount() {
        return ordercount;
    }

    public void setOrdercount(int ordercount) {
        this.ordercount = ordercount;
    }

    public Student getStudent() {
        return student;
    }

    public void setStudent(Student student) {
        this.student = student;
    }
}

StudentMapper.xml

<?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">
<mapper namespace="com.xinhua.mapper.StudentMapper">
   

    <!--查询出每个用户的信息和对应的所有订单-->
    <resultMap id="studentOrder" type="Student">
        <id column="id" property="id"></id>
        <result column="studentName" property="studentName"></result>
        <result column="gender" property="gender"></result>
        <result column="address" property="address"></result>
        <collection property="listOrder" ofType="com.xinhua.domain.Order">
            <id column="order_id" property="id"></id>
            <result column="ordername" property="ordername"></result>
            <result column="ordercount" property="ordercount"></result>
        </collection>
    </resultMap>
    <select id="findStudentOrderAll" resultMap="studentOrder">
        SELECT s.id,s.studentname,s.gender,s.address,o.id order_id,o.ordername,o.ordercount FROM student s LEFT JOIN Orders o ON s.id=o.student_id
    </select>
</mapper>


mapper接口类

public interface StudentMapper {
   
    public List<Student> findStudentOrderAll();
}

测试类:

public class TestDemo {
    SqlSessionFactory ssf = null;
    @Before
    public void creatFactory(){
        InputStream input = null;
        try {
            input = Resources.getResourceAsStream("SqlMapConfig.xml");
        } catch (IOException e) {
            e.printStackTrace();
        }
        ssf = new SqlSessionFactoryBuilder().build(input);
    }

@Test
    public void testMapper10() {
        SqlSession sqlSession = ssf.openSession();
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        List<Student> students = mapper.findStudentOrderAll();
        for (Student student : students){
            System.out.println(student.getId()+","+student.getStudentName()+","+student.getGender()+","+student.getAddress());
            List<Order> listOrder = student.getListOrder();
            for (Order order : listOrder){
                System.out.println("   "+order.getOrdername()+","+order.getOrdercount());
            }
        }
    }

2、一对多查询

用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户

一对多查询的需求:查询一个用户,与此同时查询出该用户具有的订单

主查询表:订单表

关联查询表:用户表、订单明细表、商品表

订单表

用户表

商品表

订单明细表 

对应的SQL语句:

 SELECT
  orders.id o_id,
  orders.ordername,
  student.studentname,
  student.gender,
  orderdetail.id od_id,
  orderdetail.items_count,
  orderdetail.items_all_price ,
  items.id it_id,
  items.items_name,
  items.items_price
FROM ORDERs,student,orderdetail,items


WHERE orders.student_id = student.id
  AND orders.id = orderdetail.orders_id
  AND orderdetail.items_id = items.id

用户表

相比之前一对一,变化在student类多了一个List<Order> orderList

public class Student {
    private int id;
    private String studentName;
    private String gender;
    private String address;
    private String email;
    private String remark;
    private List<Order> listOrder;

    public Student() {
    }

    public Student( String studentName, String gender, String address, String email, String remark) {

        this.studentName = studentName;
        this.gender = gender;
        this.address = address;
        this.email = email;
        this.remark = remark;
    }

    public int getId() {
        return id;
    }

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

    public String getStudentName() {
        return studentName;
    }

    public void setStudentName(String studentName) {
        this.studentName = studentName;
    }

    public String getGender() {
        return gender;
    }

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

    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 getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }

    public List<Order> getListOrder() {
        return listOrder;
    }

    public void setListOrder(List<Order> listOrder) {
        this.listOrder = listOrder;
    }
}

Order

public class Order {
    private int id;
    private String ordername;
    private int ordercount;
    private Student student;
   
    private List<OrderDetail> orderDetailList;

    public List<OrderDetail> getOrderDetailList() {
        return orderDetailList;
    }

    public void setOrderDetailList(List<OrderDetail> orderDetailList) {
        this.orderDetailList = orderDetailList;
    }

    public int getId() {
        return id;
    }

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

    public String getOrdername() {
        return ordername;
    }

    public void setOrdername(String ordername) {
        this.ordername = ordername;
    }

    public int getOrdercount() {
        return ordercount;
    }

    public void setOrdercount(int ordercount) {
        this.ordercount = ordercount;
    }

    public Student getStudent() {
        return student;
    }

    public void setStudent(Student student) {
        this.student = student;
    }
}

商品表items

    private int id;
    private String items_name;
    private int items_price;

    public int getId() {
        return id;
    }

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

    public String getItems_name() {
        return items_name;
    }

    public void setItems_name(String items_name) {
        this.items_name = items_name;
    }

    public int getItems_price() {
        return items_price;
    }

    public void setItems_price(int items_price) {
        this.items_price = items_price;
    }
}

订单明细表 

public class OrderDetail {
    private int id;
    private int items_count;
    private int items_all_price;
    private Order order;
    private List<Items> listItems;

    public List<Items> getListItems() {
        return listItems;
    }

    public void setListItems(List<Items> listItems) {
        this.listItems = listItems;
    }

    public Order getOrder() {
        return order;
    }

    public void setOrder(Order order) {
        this.order = order;
    }

    public int getId() {
        return id;
    }

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

    public int getItems_count() {
        return items_count;
    }

    public void setItems_count(int items_count) {
        this.items_count = items_count;
    }

    public int getItems_all_price() {
        return items_all_price;
    }

    public void setItems_all_price(int items_all_price) {
        this.items_all_price = items_all_price;
    }
}

OrderMapper.xml

<?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">
<mapper namespace="com.xinhua.mapper.OrderMapper">
<resultMap id="orderStudentDetailItems" type="com.xinhua.domain.Order">
        <id column="o_id" property="id"></id>
        <result column="ordername" property="ordername"></result>
        <association property="student" javaType="Student">
            <result column="studentName" property="studentName"></result>
            <result column="gender" property="gender"></result>
        </association>
        <!-- 一对多关联映射 -->
        <collection property="orderDetailList" ofType="com.xinhua.domain.OrderDetail">
            <id column="od_id" property="id"></id>
            <result column="items_count" property="items_count"></result>
            <result column="items_all_price" property="items_all_price"></result>
            <collection property="listItems" ofType="com.xinhua.domain.Items">
                <id column="it_id" property="id"></id>
                <result column="items_name" property="items_name"></result>
                <result column="items_price" property="items_price"></result>
            </collection>
        </collection>
    </resultMap>
    <select id="findOrderStudentDetailItems" resultMap="orderStudentDetailItems">
        SELECT
		  orders.id o_id,
		  orders.ordername,
		  student.studentname,
		  student.gender,
		  orderdetail.id od_id,
		  orderdetail.items_count,
		  orderdetail.items_all_price ,
		  items.id it_id,
		  items.items_name,
		  items.items_price
		FROM ORDERs,student,orderdetail,items


		WHERE orders.student_id = student.id
		  AND orders.id = orderdetail.orders_id
		  AND orderdetail.items_id = items.id

    </select>
</mapper>

mapper接口类

public interface OrderMapper {
 
    public List<Order> findOrderStudentDetailItems();
}

测试类:

public class TestDemo {
    SqlSessionFactory ssf = null;
    @Before
    public void creatFactory(){
        InputStream input = null;
        try {
            input = Resources.getResourceAsStream("SqlMapConfig.xml");
        } catch (IOException e) {
            e.printStackTrace();
        }
        ssf = new SqlSessionFactoryBuilder().build(input);
    }

    @Test
    public void testMapper11() {
        SqlSession sqlSession = ssf.openSession();
        OrderMapper mapper = sqlSession.getMapper(OrderMapper.class);
        List<Order> orderList = mapper.findOrderStudentDetailItems();
        for (Order order : orderList){
            System.out.println(order.getId()+","+order.getOrdername()+","+order.getOrdercount()+","+order.getStudent().getStudentName());
            List<OrderDetail> orderDetailList = order.getOrderDetailList();
            for (OrderDetail orderDetail : orderDetailList){
                System.out.println("   "+orderDetail.getId()+","+orderDetail.getItems_count()+","+orderDetail.getItems_all_price());
                List<Items> list = orderDetail.getListItems();
                for (Items listItems : list){
                    System.out.println("        "+listItems.getId()+","+listItems.getItems_name()+","+listItems.getItems_price());
                }
            }
        }
    }

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

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

相关文章

向日葵远程工具的使用Mysql5.7的安装与配置

目录 一、向日葵远程安装与使用 二、Mysql 5.7 安装与配置 2.1 安装 2.2 Navicat Premium 12 测试连接 本机测试连接 外部访问MySQL测试连接 三、思维导图 一、向日葵远程安装与使用 简介&#xff1a; 向日葵远程控制是一款用于对远程PC进行管理和服务的软件,拥有5秒快速…

二阶偏导数(隐函数)

定义&#xff0c;方法 一般型 复杂型

如何修复 SQL Server 数据库中的恢复挂起状态?

当我们想与关系数据库交互时&#xff0c;SQL 就会出现并帮助用户与数据库进行交互。SQL 从高级语言中获取用户的输入&#xff0c;然后访问将代码转换为机器可理解的形式。SQL 确实会恢复数据库文件&#xff0c;但有时 SQL 服务器恢复暂挂阶段会进入帐户&#xff0c;这会停止恢复…

海外数据中心代理与住宅代理:优缺点全面对比

数据中心代理和住宅代理是为了匿名而开发的&#xff0c;通过替换网站眼中您自己的 IP 地址。然而&#xff0c;它们在价格、功能、性能或最佳用例方面存在一些差异。那么&#xff0c;这些代理类型到底有什么相似点和不同点呢&#xff1f; 一、什么是数据中心代理&#xff1f; 1…

Hive用户自定义函数之UDF开发

在进行大数据分析或者开发的时候&#xff0c;难免用到Hive进行数据查询分析&#xff0c;Hive内置很多函数&#xff0c;但是会有一部分需求需要自己开发&#xff0c;这个时候就需要自定义函数了&#xff0c;Hive的自定义函数开发非常方便&#xff0c;今天首先讲一下UDF的入门开发…

人工智能大模型:定义、发展和应用

⭐简单说两句⭐ ✨ 正在努力的小新~ &#x1f496; 超级爱分享&#xff0c;分享各种有趣干货&#xff01; &#x1f469;‍&#x1f4bb; 提供&#xff1a;模拟面试 | 简历诊断 | 独家简历模板 &#x1f308; 感谢关注&#xff0c;关注了你就是我的超级粉丝啦&#xff01; &…

【基础python】条件语句 | 循环

条件语句 if elif else python中和绝大数语言类似&#xff0c;具有能够判断语句顺序的语法 if elif else 分别对应C的 if else if else if 条件为真进入语句 &#xff0c;反之则不进入 如果if 为假&#xff0c;存在else 则会进入else 如果if 为假 &#xff0c;存在…

数据库分区分表

分区分表 为什么要分库分表 软件时代&#xff0c;传统应用都有这样一个特点&#xff1a;访问量、数据量都比较小&#xff0c;单库单表都完全可以支撑整个业务。随着互联网的发展和用户规模的迅速扩大&#xff0c;对系统的要求也越来越高。因此传统的MySQL单库单表架构的性能问…

探索 Vue 实例方法的魅力:提升 Vue 开发技能(下)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

Spring的bean的生命周期!!!

一.单例模式 单例&#xff1a;[启动容器]--->通过构造方法&#xff08;创建对象&#xff09;---->调用set方法&#xff08;注入&#xff09;--->调用init方法&#xff08;初始化&#xff09;----[容器关闭]----->调用destroy方法&#xff08;销毁&#xff09; app…

教你用python画图—Turtle详细教程

Turtle模块绝对是吸引非专业代码开发者人员学习python入门的好工具 通过turtle几行代码的执行软件就会画出漂亮的图形&#xff0c;美观而且有成就感&#xff0c;这样一下子对python编程就产生了兴趣。 这些漂亮的图形如三角形、五角星、机器猫等。在写代码的时候改变几个参数…

反距离加权水平内插,附matlab代码(ERA5和GNSS站点不并址的处理方法之水平补偿)

1.内插方法 我在学习过程&#xff0c;内插方法为反距离加权水平内插&#xff0c;分享我的方法和公式&#xff0c;以及matlab代码。 2.使用该内插法的原因 GNSS与ERA5格网位置不并址&#xff0c;需要进行水平方向和垂直方向的补偿的补偿获得。水平方向不并址如第3节图所示&am…

数字人私人定制

数字人是什么&#xff1f; 在回答这个问题之前&#xff0c;我们先回答另一个问题&#xff0c;人如何与人工智能交流&#xff1f;目前可以通过文字、语音、电脑屏幕、手机屏幕、平板、虚拟现实设备等和人工智能交流&#xff0c;为了得到更好的交流体验&#xff0c;人工智能必然…

css sourcemap 源代码映射

vue.config.js css: {// Enable CSS source maps.sourceMap: process.env.NODE_ENV ! production, }重新运行&#xff1a;yarn serve 效果&#xff1a;

three.js Raycaster(鼠标点击选中模型)

效果&#xff1a; 代码&#xff1a; <template><div><el-container><el-main><div class"box-card-left"><div id"threejs" style"border: 1px solid red"></div><div class"box-right"…

LiveGBS流媒体平台GB/T28181功能-国标级联对接海康大华宇视华为等上级平台选择通道支持只看已选只看未选

LiveGBS功能国标级联对接海康大华宇视华为等上级平台选择通道支持只看已选只看未选 1、国标级联2、只看已选3、只看未选4、搭建GB28181视频直播平台 1、国标级联 LiveGBS可以作为下级平台&#xff0c;级联到第三方国标平台&#xff0c;详见&#xff1a; LiveGBS国标GB/T28181流…

dctcp 可扩展、低时延图解

理想 reno 和理想 dctcp 的单流 cwnd-time 演化图如下&#xff1a; 很直观地展现出 dctcp 锯齿小很多&#xff0c;锯齿小意味着高效。 dctcp 利用交换机反馈而来的 ecn 可精确计算导致排队超过 k 的报文比例&#xff0c;减去这一比例的 inflight 就是合适的。但 dctcp 在 re…

快速跳闸中间继电器 RXMS1-RK216 066-AD 24V 柜内安装,板后接线带中座

系列型号 RXMS1 RK 216 437快速跳闸继电器&#xff1b;RXMS1 RK 216 237快速跳闸继电器&#xff1b; RXMS1 RK 216 449快速跳闸继电器&#xff1b;RXMS1 RK 216 249快速跳闸继电器&#xff1b; RXMS1 RK 216 450快速跳闸继电器&#xff1b;RXMS1 RK 216 250快速跳闸继电器&…

5.云原生之DevOps和CICD

文章目录 怎么理解DevOps&#xff1f;所需环境介绍创建devops java项目DockerFile文件Jenkinsfiledevops.yaml文件 搭建 DevOps 项目创建凭证创建devops项目创建流水线编写流线文件运行流线 为流水线设置电子邮箱服务器设置QQ邮箱 SMTP服务器配置jenkins邮箱服务器 使用Webhook…

【C语言数组传参】规则详解

目录 数组传参介绍 数组传参规则 数组传参的实参 特殊情况一&#xff1a;sizeof&#xff08;数组名&#xff09; 特殊情况二&#xff1a;&数组名 数组传参的形参 数组传参使用数组名作为形参接收 形参如果是⼀维数组 形参如果是⼆维数组 数组传参使用指针作为形参…