作者:汤圆
集体博客: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条件
后记
其实这种写法还是比拟繁琐的,但好在用的不多;如果用的多,倡议去找一些开源的库来整合
发表回复