繁体   English   中英

从多个不同的实体收集所有子实体

[英]Collecting all child entities from multiple different entities

我有 3 个实体 A、B 和 C。

  • A 包含一对一链接的 B 实体
  • A 包含 C 实体的一对多链表
  • B 包含 C 实体的一对多链表

数据库方面有 5 个表。 各个实体的 3 个表和 2 个单独的链接表,一个包含 A 和 C 之间的链接(A_to_C),另一个包含 B 和 C 之间的链接(B_to_C)。 在我的存储库中,我试图从特定的 A 记录中检索所有 C 实体,这意味着来自 A 本身的 C 实体和通过 B 链接的 C 实体。

在传统的 SQL 中,这可以使用以下方法完成:

select C.*
from A
left join A_to_C on A_to_C.A_ID = A.ID
left join B_to_C on B_to_C.B_ID = A.B_ID
inner join C on C.ID = A_to_C.C_ID OR C.ID = B_to_C.C_ID
where A.ID = '1';

或(从 C 开始)

select C.*
from C
left join A_to_C on A_to_C.C_ID = C.ID
left join B_to_C on B_to_C.C_ID = C.ID
inner join A on A.B_ID = B_to_C.B_ID OR
                A.ID = A_to_C.A_ID
where A.ID = '1';

在这些 SQL 示例中没有指向 B 的表的链接,因为 A 包含 B 的 ID,它也是 B_to_C 中使用的 ID,所以我真的不需要它。 我也知道这些并不完全相同,但是当我只对 C 感兴趣时它们会产生相同的结果。

不过,我真的很想知道如何在 CriteriaBuilder(最好)或 JPQL 中执行此操作。 我对 jpa 还是比较陌生,所以我希望这里有人可以帮助我。

我相信,即使有机会在vanilla JPQL上取得成功,您也需要通过添加@ManyToOne方将关联转换为双向关联(或单向多对一)。 然后您可以从C开始查询。 @OneToMany端,如果你想保留它,在这种情况下成为关联的反面,但是:

@Entity
public class C {

    @ManyToOne
    @JoinTable
    private B b;

    @ManyToOne
    @JoinTable
    private A a;
}

@Entity
public class B {

    @ManyToOne
    @JoinTable
    private A a;

    @OneToMany(mappedBy = "b")
    private List<C> cs;
}

@Entity
public class A {

    @OneToMany(mappedBy = "a")
    private List<B> bs;


    @OneToMany(mappedBy = "a")
    private List<C> cs;
}

一旦你这样做了,JPQL 查询就会变成这样:

SELECT c FROM C c
LEFT JOIN c.a a
LEFT JOIN c.b b
LEFT JOIN b.a a2
WHERE a.id = :id OR a2.id = :id

如果您不同意将关联的“一侧”设为反面,那么您就不走运了。 最简单的解决方案是使用本机查询。

Eclipselink JPQL 扩展包含一个ON子句,所以也许您可以将ONMEMBER OF结合使用:

SELECT c FROM C c
LEFT JOIN A a ON c MEMBER OF a.cs
LEFT JOIN B b ON c MEMBER OF b.cs
LEFT JOIN A a2 ON b MEMBER OF a2.cs
WHERE a.id = :id OR a2.id = :id

不过,我非常怀疑它会起作用,即使它起作用,我也会警惕生成的 SQL,因为它可能不是最理想的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM