多表联合查询 - 基于注解SQL
作者:汤圆
个人博客:javalover.cc
前言
背景:Spring Boot + MybatisPlus
用MybatisPlus就是为了不写SQL,用起来方便;
但是如果需要多表联合查询,还是需要手写SQL(不过GitHub上也是有一些开源的库,可以不写SQL)
本节介绍的还是通用的写法,基于注解SQL实现的多表联合查询
简介
大概流程就是
- 先把要联合查询的参数封装到一个类里进行返回 - 结果类
- 再在mapper中注入SQL查询语句 - @Select
- 最后在service中拼接查询条件 - QueryWrapper构造器(这里没用Lambda构造器,因为它不支持编写自定义的字段名)
正文
我们就按照上面的流程来演示:
先贴一下这里我们要执行的SQL查询语句:这里只贴了我们手写的部分,还有一部分是程序在后面自动追加的(比如条件、分页),这里先不写
select device.*, car.car_number from gps_device as device left join gps_car as car on device.car_id = car.car_id
1. 定义实体结果类
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class DeviceResult extends Device implements Serializable {
/**
* 车牌号:只有这个属性是联合Car查询的,其他属性都是Device自带的
*/
private String carNumber;
/**
* 设备id
*/
private Long deviceId;
/**
* 车辆id
*/
private Long carId;
/**
* 设备类型:0-无线,1-有线
*/
private Integer deviceType;
/**
* 设备编号
*/
private String deviceNumber;
/**
* SIM卡号
*/
private String simNumber;
}
可以看到,这里我们将联合查询的carNumber封装了进去,这样返回时,就可以将设备信息和车牌号一并返回(多表联合查询的目的就是这个,联合多个表的数据进行返回)
2. mapper中注入SQL语句
这里有多种方式:
- 基于注解
- 基于xml
这里我们用的是基于注解(因为Spring Boot中xml的使用还是比较少的)
DeviceMapper.java
public interface DeviceMapper extends BaseMapper<Device> {
/**
* 联合查询 left join car
*/
@Select("select device.*, car.car_number from gps_device as device left join gps_car as car on device.car_id = car.car_id ${ew.customSqlSegment}")
Page<DeviceResult> joinCarPage(Page<?> page, @Param(Constants.WRAPPER) Wrapper<Device> wrapper);
}
代码说明:
@Select注解:注入SQL语句@Param(Constants.WRAPPER) Wrapper<Device> wrapper: 这个注解有点类似@RequestParam,用来代替SQL语句中的ew变量(如果把形参wrapper改为ew,就不需要加@Param注解);这里的构造器wrapper中的自定义SQL会自动追加到@Select语句的后面,最后的service中会有拼接结果SQL
BaseMapper:Mybatis-Plus的基类Mapper,封装了各种常用的数据库操作(增删改查分页等),有了它,一些基本的操作(增删改查等)我们就不用自己去写SQL
Page:Mybatis-Plus中的分页对象,将联合查询的数据进行分页;这里的分页相关的SQL会自动追加到wrapper包装器的后面(同上面的wrapper)
最后拼接的SQL为:
select device.*, car.car_number from gps_device as device left join gps_car as car on device.car_id = car.car_id LIMIT ?,?
其中limit ?, ?就是Page自动追加的SQL,wrapper追加的SQL在下面的service中定义
3. Service中调用mapper
此时在Service中就不能再使用Lambda表达式了,因为这里需要自定义字段名
核心代码如下:
QueryWrapper<Device> queryWrapper = new QueryWrapper<>();
queryWrapper.eq(ObjectUtil.isNotEmpty(deviceParam.getDeviceType()), "device.device_type", deviceParam.getDeviceType());
queryWrapper.like(ObjectUtil.isNotEmpty(deviceParam.getCarNumber()), "car.car_number", deviceParam.getCarNumber());
最后拼接的SQL为:(这里假设deviceType和carNumber都有传进来)
select device.*, car.car_number from gps_device as device left join gps_car as car on device.car_id = car.car_id where (device.device_number = ? and car.car_number = ?) LIMIT ?,?
总结
基于注解的多表联合查询,分三步:
- 定义实体结果类:封装需要多表联合查询的数据
- 在mapper中注入SQL语句
- 在service中调用mapper,拼接where条件
后记
其实这种写法还是比较繁琐的,但好在用的不多;如果用的多,建议去找一些开源的库来整合
多表联合查询 - 基于注解SQL的更多相关文章
- springdata 查询思路:基本的单表查询方法(id,sort) ---->较复杂的单表查询(注解方式,原生sql)--->实现继承类---->复杂的多表联合查询 onetomany
springdata 查询思路:基本的单表查询方法(id,sort) ---->较复杂的单表查询(注解方式,原生sql)--->实现继承类---->复杂的多表联合查询 onetoma ...
- SQL Server -- 回忆笔记(二):增删改查,修改表结构,约束,关键字使用,函数,多表联合查询
SQL Server知识点回忆篇(二):增删改查,修改表结构,约束,关键字使用,函数,多表联合查询 1. insert 如果sql server设置的排序规则不是简体中文,必须在简体中文字符串前加N, ...
- mybatis:开发环境搭建--增删改查--多表联合查询(多对一)
什么是mybatisMyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索.MyBatis使用简单的XML或 ...
- yii 多表联合查询的几种方法
yii多表联合查询, 第一种,用command,自己拼接sql语句执行查询 第二种,用AR,model需继承下面的ar,执行queryall或queryrow方法 <?php //applica ...
- Dynamic CRM 2013学习笔记(九)CrmFetchKit.js介绍:Fetchxml、多表联合查询, 批量更新
CrmFetchKit.js是一个跨浏览器的一个类库,允许通过JavaScript来执行fetch xml的查询,还可以实现批量更新,分页查询等.目前已支持Chrome 25, Firefox 19 ...
- SharePoint 2013 列表多表联合查询
在SharePoint的企业应用中,遇到复杂的逻辑的时候,我们会需要多表查询:SharePoint和Sql数据表一样,也支持多表联合查询,但是不像Sql语句那样简单,需要使用SPQuery的Joins ...
- MyBatis 多表联合查询及优化 以及自定义返回结果集
下面就来说一下 mybatis 是通过什么来实现多表联合查询的.首先看一下表关系,如图: 这 里,我已经搭好了开发的环境,用到的是 SpringMVC + Spring + MyBatis,当然,为了 ...
- 一步步学Mybatis-实现多表联合查询(4)
上一章节中我们已经完成了对单表的CRUD操作,接下来今天这一讲讲述的是关于Mybatis在多表查询时候的应用,毕竟实际业务中也是多表的联合查询比较多嘛~ 还记得最一开始我们新建过一张Website表吗 ...
- MyBatis 多表联合查询,字段重复的解决方法
MyBatis 多表联合查询,两张表中字段重复时,在配置文件中,sql语句联合查询时使用字段别名,resultMap中对应的column属性使用相应的别名: <resultMap type=&q ...
随机推荐
- CVPR2021 | 华为诺亚实验室提出Transformer in Transformer
前言: transformer用于图像方面的应用逐渐多了起来,其主要做法是将图像进行分块,形成块序列,简单地将块直接丢进transformer中.然而这样的做法忽略了块之间的内在结构信息,为此,这篇论 ...
- 『动善时』JMeter基础 — 2、JMeter的安装和启动
1.安装Java环境 由于JMeter是纯Java的桌面应用程序,因此它的运行环境需要Java环境,即需要安装JDK或JRE.(也就是安装JDK环境) 步骤简要说明: 下载并安装JDK 配置环境变量 ...
- DexClassLoader动态加载分析
转载自:http://www.blogfshare.com/dexclassloader.html 看到原来有把原始的dex文件加密保存,然后解密后使用DexClassLoader加载文件的方法,就来 ...
- hdu3786 Floyd或搜索 水题
题意: 找出直系亲属 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- LA3213加密
题意: 白书上有些题的题意说的太蛋疼了,这个题的意思是说有两种加密方式,一种是交换位置,另一种是一一映射,交换位置是指如ABCD 可以加密成DCBA 也可以加密成ACBD就是把某些字母的位 ...
- 基于 registry 搭建 Docker 私有镜像仓库
今天主要介绍使用 registry 来搭建 Docker私有镜像仓库,方便在公司内部项目中使用,registry 也是 Docker 官方提供的一个镜像,操作也很简单. dockerhub: http ...
- C# 通过DataSet 获取SQL 存储过程返回的多个结果集(tables)
测试数据:Northwind 链接地址: https://files.cnblogs.com/files/louiszh/NorthWind.zip 首先创建一个测试存储过程: IF EXISTS ( ...
- C#中的元组(Tuple)和结构体(struct)
在正常的函数调用中,一个函数只能返回一个类型的值,但在某些特殊情况下,我们可能需要一个方法返回多个类型的值,除了通过ref,out或者泛型集合可以实现这种需求外,今天,讲一下元组和结构体在这一方面的应 ...
- 【Matlab】BASK的调试与解调仿真
索引 一.BASK的调制 1.1 曼彻斯特码 1.2 增益控制 1.3 常量求和 1.4 与载波相乘 1.5 波形预览 1.6 参数设置(参考) 二.BASK的解调 2.1 滤波 2.2 信号比较 2 ...
- MySQL redo与undo日志解析
前言: 前面文章讲述了 MySQL 系统中常见的几种日志,其实还有事务相关日志 redo log 和 undo log 没有介绍.相对于其他几种日志而言, redo log 和 undo log 是更 ...