多表联合查询-基于注解SQL
作者:汤圆
个⼈博客:
前⾔
背景:Spring Boot + MybatisPlus
⽤MybatisPlus就是为了不写SQL,⽤起来⽅便;
但是如果需要多表联合查询,还是需要⼿写SQL(不过GitHub上也是有⼀些开源的库,可以不写SQL)
本节介绍的还是通⽤的写法,基于注解SQL实现的多表联合查询
简介
⼤概流程就是
1. 先把要联合查询的参数封装到⼀个类⾥进⾏返回 - 结果类
2. 再在mapper中注⼊SQL查询语句 - @Select
3. 最后在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;
sql left join 多表连接
/**
* 设备编号
*/
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.DeviceType()), "device.device_type", DeviceType());
queryWrapper.like(ObjectUtil.CarNumber()), "car.car_number", CarNumber());
最后拼接的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 ?,?总结
基于注解的多表联合查询,分三步:
1. 定义实体结果类:封装需要多表联合查询的数据
2. 在mapper中注⼊SQL语句
3. 在service中调⽤mapper,拼接where条件
后记
其实这种写法还是⽐较繁琐的,但好在⽤的不多;如果⽤的多,建议去⼀些开源的库来整合

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。