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

如何用PostgreSQL及Spring JPA/Hibernate关联父表与两无关子表获目标记录

父表关联多子表的查询解决方案

1. 获取总计13条目标记录

你需要的是C1、C2中匹配父表的记录集合(无重复合并),可通过以下两种方式实现:

方式一:原生SQL(JPA/Hibernate支持UNION ALL)

JPA原生SQL查询完全支持UNION ALL,直接编写如下语句即可:

SELECT p.*, c1.*, NULL AS c2_col1, NULL AS c2_col2, ...
FROM parent p
INNER JOIN child1 c1 ON p.id = c1.parent_id
UNION ALL
SELECT p.*, NULL AS c1_col1, NULL AS c1_col2, ..., c2.*
FROM parent p
INNER JOIN child2 c2 ON p.id = c2.parent_id;

注意:两个子查询的列数、数据类型必须一致,不存在的列用NULL填充,需将示例中的c1_col1、c2_col2替换为实际字段名。

方式二:JPA Query + 代码合并

若不想用UNION,可分别查询两个子表关联父表的结果,再在业务代码中合并集合:

// 查询C1关联父表的所有记录
List<ParentChild1DTO> c1List = entityManager.createQuery(
    "SELECT new com.yourpackage.ParentChild1DTO(p, c1) FROM Parent p JOIN p.child1 c1",
    ParentChild1DTO.class
).getResultList();

// 查询C2关联父表的所有记录
List<ParentChild2DTO> c2List = entityManager.createQuery(
    "SELECT new com.yourpackage.ParentChild2DTO(p, c2) FROM Parent p JOIN p.child2 c2",
    ParentChild2DTO.class
).getResultList();

// 转换为统一DTO并合并
List<ParentChildCombinedDTO> resultList = new ArrayList<>();
resultList.addAll(convertToCombinedDTO(c1List));
resultList.addAll(convertToCombinedDTO(c2List));

需提前定义对应DTO类封装查询结果,convertToCombinedDTO方法负责将不同子表的DTO转换为统一格式。

2. Limit 8时返回C1全部5条+ C2的3条记录

同样提供两种实现方式:

方式一:原生SQL

通过UNION ALL结合LIMIT控制,先取C1全部记录,再取C2前3条:

(SELECT p.*, c1.*, NULL AS c2_col1, NULL AS c2_col2, ...
FROM parent p
INNER JOIN child1 c1 ON p.id = c1.parent_id)
UNION ALL
(SELECT p.*, NULL AS c1_col1, NULL AS c1_col2, ..., c2.*
FROM parent p
INNER JOIN child2 c2 ON p.id = c2.parent_id
LIMIT 3)
LIMIT 8;

方式二:JPA Query + 代码控制

先查询C1全部5条记录,再查询C2前3条,合并后得到目标结果:

// 查询C1全部关联记录并转换为统一DTO
List<ParentChildCombinedDTO> c1Result = convertToCombinedDTO(
    entityManager.createQuery(
        "SELECT new com.yourpackage.ParentChild1DTO(p, c1) FROM Parent p JOIN p.child1 c1",
        ParentChild1DTO.class
    ).getResultList()
);

// 查询C2前3条关联记录并转换为统一DTO
List<ParentChildCombinedDTO> c2Result = convertToCombinedDTO(
    entityManager.createQuery(
        "SELECT new com.yourpackage.ParentChild2DTO(p, c2) FROM Parent p JOIN p.child2 c2",
        ParentChild2DTO.class
    ).setMaxResults(3)
    .getResultList()
);

// 合并最终结果
List<ParentChildCombinedDTO> finalResult = new ArrayList<>();
finalResult.addAll(c1Result);
finalResult.addAll(c2Result);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 21:35:16