Mybatis之多表查询
目录
一、简介
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 mapperPUBLIC "-//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;@Beforepublic void creatFactory(){InputStream input = null;try {input = Resources.getResourceAsStream("SqlMapConfig.xml");} catch (IOException e) {e.printStackTrace();}ssf = new SqlSessionFactoryBuilder().build(input);}@Testpublic 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语句:
SELECTorders.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,itemsWHERE orders.student_id = student.idAND orders.id = orderdetail.orders_idAND 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 mapperPUBLIC "-//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">SELECTorders.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_priceFROM ORDERs,student,orderdetail,itemsWHERE orders.student_id = student.idAND orders.id = orderdetail.orders_idAND orderdetail.items_id = items.id</select>
</mapper>
mapper接口类
public interface OrderMapper {public List<Order> findOrderStudentDetailItems();
}
测试类:
public class TestDemo {SqlSessionFactory ssf = null;@Beforepublic void creatFactory(){InputStream input = null;try {input = Resources.getResourceAsStream("SqlMapConfig.xml");} catch (IOException e) {e.printStackTrace();}ssf = new SqlSessionFactoryBuilder().build(input);}@Testpublic 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());}}}}
相关文章:
Mybatis之多表查询
目录 一、简介 1、使用嵌套查询: 2、使用多个 SQL 语句: 3、使用关联查询: 4、使用自定义映射查询: 二、业务场景 三、示例 1、一对一查询 2、一对多查询 一、简介 MyBatis 是一个优秀的持久层框架,它提供了强大的支持来执…...
部署node.js+express+mongodb(更新中)
1-Linux服务器部署MongoDB 1.升级 yum -y update 2.下载MongoDB安装包 3.上传安装包 上传目录 : /usr/local/ 2-配置MongoDB环境变量并启动 1.配置环境变量全局启动 vi ~/.bash_profile 使用i命令进入编辑模式 添加: export PATH/usr/local/mongodb/bin:$P…...
百度CTO王海峰:文心一言用户规模破1亿
“文心一言用户规模突破1亿。”12月28日,百度首席技术官、深度学习技术及应用国家工程研究中心主任王海峰在第十届WAVE SUMMIT深度学习开发者大会上宣布。会上,王海峰以《文心加飞桨,翩然赴星河》为题作了主旨演讲,分享了飞桨和文…...
简单最短路径算法
前言 图的最短路径算法主要包括: 有向无权图的单源最短路径 宽度优先搜索算法(bfs) 有向非负权图的单源最短路径 迪杰斯特拉算法(Dijkstra) 有向有权图的单源最短路径 贝尔曼福特算法(Bellman-Ford&#…...
答案解析——C语言—第3次作业—算术操作符与关系操作符
本次作业链接如下: C语言—第3次作业—算术操作符与关系操作符 1.在C语言中,表达式 7 / 2 的结果是多少? - A) 3.5 - B) 3 - C) 4 - D) 编译错误 答案:B) 3 解析: 在C语言中,当两个整数进行除法运算时&…...
【数据结构】二叉树的链式实现
树是数据结构中非常重要的一种,在计算机的各方个面都有他的身影 此篇文章主要介绍二叉树的基本操作 目录 二叉树的定义:二叉树的创建:二叉树的遍历:前序遍历:中序遍历:后序遍历: 二叉树节点个数…...
八、QLayout 用户基本资料修改(Qt5 GUI系列)
目录 一、设计需求 二、实现代码 三、代码解析 四、总结 一、设计需求 在很多应用程序中会有用户注册或用户编辑信息等界面。本文就设计一个用户信息编辑界面。要求包含用户名、姓名、性别、部门、年龄、头像、个人说明等信息。 二、实现代码 #ifndef DIALOG_H #define D…...
tomcat、java、maven
JDK|JRE Tomcat官网介绍的更清楚 Java 环境安装 安装 wget https://builds.openlogic.com/downloadJDK/openlogic-openjdk/8u392-b08/openlogic-openjdk-8u392-b08-linux-x64.tar.gz tar -xf openlogic-openjdk-8u392-b08-linux-x64.tar.gz mv openlogic-openjdk…...
IDEA好用插件
CodeGlance Pro 右侧代码小地图 Git Commit Template git提交信息模板 IDE Eval Reset 无限试用IDEA Maven Helper 图形化展示Maven项 One Dark theme 好看的主题 SequenceDiagram 展示方法调用链 Squaretest 生成单元测试 Translation 翻译 Lombok lombok插件…...
面试官:CSS3新增了哪些新特性?
面试官:CSS3新增了哪些新特性? 一、是什么 css,即层叠样式表(Cascading Style Sheets)的简称,是一种标记语言,由浏览器解释执行用来使页面变得更美观 css3是css的最新标准,是向后兼…...
Vite5 + Vue3 + Element Plus 前端框架搭建
为了开发一套高效使用的 Vite5 + Vue3 + Element Plus 前端框架,你可以按照以下步骤进行。话不多说,先上演示地址:Vue Shop Vite。 1, 安装开发环境 开发之前,确保你的电脑已经安装了 Node.js(建议使用最新稳定版 LTS),然后安装 Vite CLI。在命令行中运行以下命令: …...
STM32 内部 EEPROM 读写
STM32 的某些系列 MCU 自带 EEPROM。笔者使用的 STM32L151RET6 自带 16 KB 的 EEPROM,可以用来存储自定义的数据。在芯片选型时,自带 EEPROM 也可以作为一个考量点,省去了在外接 EEPROM 的烦恼。 下面简单介绍下 STM32 内部 EEPROM 的读写流…...
androidStudio sync failed GradlePropertiesModel (V2)
大家在增加模块的时候经常遇到吧?重启后就好了。 Cannot get GradlePropertiesModel (V2) for project ‘GradleProject{path’:app’}’ 然而,今天开机以后,无论如何,点击gradle的大象图标(Sync Project with Gradle Files)&…...
结构方程模型(SEM)
结构方程模型(Structural Equation Modeling)是分析多变量间因果关系的利器,在众多学科领域具有巨大应用潜力。我们前期推出的《基于R语言结构方程模型》课程通过结构方程原理介绍、结构方程全局和局域估计、模型构建和调整、潜变量分析、复合…...
基于UDP的网络编程
UDP服务端 #ifdef _WIN32 #define _WINSOCK_DEPRECATED_NO_WARNINGS #define close closesocket #include <winsock2.h> #else #include <arpa/inet.h> #include <netdb.h> #include <netinet/in.h> #in…...
vue判断组件有没有传入的slot有就渲染slot没有就渲染内部节点
GPT4国内站点:海鲸AI 在 Vue 中,你可以使用 $slots 对象来检查是否有特定的插槽内容被传递给组件。Vue 3 中的 $slots 是一个对象,其中包含了所有插槽的引用。如果插槽没有内容,对应的插槽属性将会是 undefined。 下面是一个例子…...
MS713/MS713T:CMOS 低压、4Ω四路单刀单掷开关,替代ADG713
产品简述 MS713/MS713T 是一款单芯片 CMOS 4 路可选择开关,具有低 功耗、高开关速度、低导通阻抗、低漏电和高带宽特性。其工作 电压范围是 1.8V 到 5.5V ,可以广泛应用在电池供电仪器仪表、新 一代的模数转换和数模转换系统中。其高带宽特性可用在 …...
Android 内容生成pdf文件
1.引入itext7 implementation com.itextpdf:itext7-core:7.1.13上面比较大,可以直接下载需要集成的jar包 implementation files(libs\\layout-7.1.13.jar) implementation files(libs\\kernel-7.1.13.jar) implementation files(libs\\io-7.1.13.jar) implementatio…...
Javaweb-日程管理
094.日程管理第二期_准备数据库和实体类_哔哩哔哩_bilibili navicat 下载 学生认证: Navicat 教育版 - 学生许可证 | Navicat navicat连接mysql 使用navicat连接mysql数据库创建数据库、表、转储sql文件,导入sql数据_哔哩哔哩_bilibili...
SwiftUI之深入解析如何创建一个灵活的选择器
一、前言 在 Dribbble 上找到的设计的 SwiftUI 实现时,可以尝试通过一些酷炫的筛选器扩展该项目以缩小结果列表。筛选视图将由两个独立的筛选选项组成,两者都有一些可选项可供选择。但是,在使用 UIKit 时,总是将这种类型的视图实…...
IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...
Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...
深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...
Linux 中如何提取压缩文件 ?
Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...
PHP 8.5 即将发布:管道操作符、强力调试
前不久,PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5!作为 PHP 语言的又一次重要迭代,PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是,借助强大的本地开发环境 ServBay&am…...
MySQL:分区的基本使用
目录 一、什么是分区二、有什么作用三、分类四、创建分区五、删除分区 一、什么是分区 MySQL 分区(Partitioning)是一种将单张表的数据逻辑上拆分成多个物理部分的技术。这些物理部分(分区)可以独立存储、管理和优化,…...
