关于java:多表联合查询基于注解SQL

38次阅读

共计 2474 个字符,预计需要花费 7 分钟才能阅读完成。

作者:汤圆

集体博客:javalover.cc

前言

背景: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;

    /**
     * 设施编号
     */
    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 ?,?

总结

基于注解的多表联结查问,分三步:

  1. 定义实体后果类:封装须要多表联结查问的数据
  2. 在 mapper 中注入 SQL 语句
  3. 在 service 中调用 mapper,拼接 where 条件

后记

其实这种写法还是比拟繁琐的,但好在用的不多;如果用的多,倡议去找一些开源的库来整合

正文完
 0