You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过一次findAll()查询获取两个关联实体的合并结果?

问题描述

现有两个实体Report1和Report2,字段对应关系如下:

Report1Report2
sidsid
namename
salarydepartment

注:report1.sid == report2.sid,且sid在两个实体中唯一且一一对应

我的目标是合并两个实体的数据展示,期望结果字段为sid、name、salary、department。目前可以分别调用findAll()获取各自数据,但希望一次查询得到合并后的结果。试过用@JoinColumn,但会在数据库表新增列,不符合需求。

实体类代码

Report1

@AllArgsConstructor
@NoArgsConstructor
@ToString
@Data
@Entity
@Table(name = "REPORT1")
public class Report1 {
    @Id
    private String SID;
    private String NAME;
    private double AMOUNT; // 对应需求中的salary
}

Report2

@AllArgsConstructor
@NoArgsConstructor
@ToString
@Data
@Entity
@Table(name = "REPORT2")
public class Report2 {
    @Id
    private String SID;
    private String DEPARTMENT;
    private String NAME;
}

仓库接口代码

public interface Report1Repository extends JpaRepository<Report1, Integer> {
}

public interface Report2Repository extends JpaRepository<Report2, Integer> {
}
解决方案

无需修改数据库表,以下几种方法均可实现一次查询合并数据:

方法1:自定义DTO + JPQL查询

  1. 创建DTO类接收合并结果:
@Data
@AllArgsConstructor
public class MergedReportDTO {
    private String sid;
    private String name;
    private double salary; // 对应Report1的AMOUNT
    private String department;
}
  1. 在任意仓库接口(如Report1Repository)中添加JPQL查询:
public interface Report1Repository extends JpaRepository<Report1, Integer> {
    @Query("SELECT new com.yourpackage.MergedReportDTO(r1.SID, r1.NAME, r1.AMOUNT, r2.DEPARTMENT) " +
           "FROM Report1 r1 JOIN Report2 r2 ON r1.SID = r2.SID")
    List<MergedReportDTO> findMergedReports();
}

提示:替换com.yourpackage为实际DTO包路径;name可选择r1.NAME或r2.NAME,按需调整即可。

方法2:接口投影(无需创建DTO)

直接定义投影接口,Spring Data JPA会自动生成实现类:

public interface MergedReportProjection {
    String getSid();
    String getName();
    @Value("#{target.AMOUNT}")
    double getSalary();
    @Value("#{target.DEPARTMENT}")
    String getDepartment();
}

在仓库中添加查询方法:

public interface Report1Repository extends JpaRepository<Report1, Integer> {
    @Query("SELECT r1.SID AS sid, r1.NAME AS name, r1.AMOUNT AS salary, r2.DEPARTMENT AS department " +
           "FROM Report1 r1 JOIN Report2 r2 ON r1.SID = r2.SID")
    List<MergedReportProjection> findMergedReports();
}

方法3:原生SQL查询

如果JPQL不够灵活,可使用原生SQL:

public interface Report1Repository extends JpaRepository<Report1, Integer> {
    @Query(value = "SELECT r1.SID AS sid, r1.NAME AS name, r1.AMOUNT AS salary, r2.DEPARTMENT AS department " +
                   "FROM REPORT1 r1 JOIN REPORT2 r2 ON r1.SID = r2.SID",
           nativeQuery = true)
    List<MergedReportDTO> findMergedReports();
}

该方法同样支持用DTO或投影接口接收结果。


内容的提问来源于stack exchange,提问作者JJJJJJ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 07:38:17