簡體   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