如何通过一次findAll()查询获取两个关联实体的合并结果?
问题描述
现有两个实体Report1和Report2,字段对应关系如下:
| Report1 | Report2 |
|---|---|
| sid | sid |
| name | name |
| salary | department |
注:
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查询
- 创建DTO类接收合并结果:
@Data @AllArgsConstructor public class MergedReportDTO { private String sid; private String name; private double salary; // 对应Report1的AMOUNT private String department; }
- 在任意仓库接口(如
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
相关产品推荐
相关产品推荐

