2016-09-29 62 views
2

這看起來可能很基本,但已經很晚了,我在遇到以下問題。HQL左加入條件

class Group { 

    @Id 
    String id; 
} 

class Participation { 

    @Id 
    String id; 

    @ManyToOne 
    @JoinColumn(name = "GROUP_ID") 
    Group group; 

    @ManyToOne 
    @JoinColumn(name = "USER_ID") 
    User user; 
} 

class User { 

    @Id 
    String id; 

    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY) 
    Set<Participation> participations; 
} 

Class diagram

所以

參與 - > 1組

和用戶1 < - >ñ參與

我怎樣才能檢索到所有羣體有,對於給定的用戶,相關的參與(或空無是)?我一直在玩加盟取,但無濟於事到目前爲止...

非常感謝,

CN

PS。我可以在SQL這樣做:

select g.d, p.id 
from group as g 
left join participation as p 
on p.group_id = g.id and p.user_id = 2; 
+0

編輯:添加圖和更好的SQL解決方案... – ChambreNoire

回答

-1

您需要映射在Group實體participation關係。如果ParticipationGroup之間的關係是1..1:

class Group { 
    String id 
    List<Participation> participations 
} 

的JPQL可以是:

SELECT g.id, p.id FROM Group g 
JOIN g.participations p 
JOIN p.user user 
WHERE user.id = :idUser 

您可以收到此信息爲List<Object[]>Object[0]是組ID和Object[1]是參與ID)或使用SELECT NEW

沒有地圖集團/參與的關係,你可以這樣做:

SELECT g.id, p.id FROM Group g, Participation p 
JOIN p.user user 
JOIN p.group groupp 
WHERE g.id = groupp.id 
AND user.id = :idUser 

但是使用這個策略,你不能做一個LEFT JOIN。以上查詢行爲如JOIN

在Hibernate中,您映射您想要查詢的關係的一側是正常的。所以,我推薦第一種方法,繪製關係。

+0

恐怕參與和組之間的關係不是1:1(我已經添加了原始問題圖)。 – ChambreNoire

+0

@ChambreNoire,沒問題!我編輯了我的問題,但以相同的方式工作 – Dherik

+0

沒有添加組>參與關聯的方法嗎? – ChambreNoire

3

(可能是一些在HQL本身,而是想法錯字應該是正確的)

你問什麼,根據你的SQL和描述,是找出所有Participation(及其相應Group)的基礎上User,這簡直是​​

select p.id, p.group.id from Participation p where p.user.id = :userId 

,使之更好,則應該取實體:

from Participation p left join fetch p.group where p.user.id = :userId 

在理解你想要做的事情時存在一些混淆: 你想要所有的組(不管條件如何)。而且,對於給定的用戶,您希望查找用戶所涉及的所有組和參與者。

雖然它應該可以使用鼠標右鍵外連接:

select g, p from Participation p 
    right outer join p.group g 
    where p.user.id=:userId 

或者,在以後的Hibernate的版本(?> = 5.1),它允許顯式連接(以前沒有嘗試過,你可能試試看)如果你正在使用JPQL(更換withon):

select g, p from Group g 
    left outer join Participation p 
     with p.group = g 
    left outer join p.user u 
    where u.id = :userId 

或者你可以使用其他技術,如子查詢等,但我寧願在你的情況下,他們分成簡單的查詢,並做了簡單的聚合在你的代碼中。

的基本思想是讓所有羣體

  1. 查詢:from Groups
  2. 查詢爲用戶的所有參股:from Participation p join fetch p.group where p.user.id=:userId

然後你就可以很容易地對其進行聚合的形式,你想要,例如Map<Group, List<Participation>>,甚至更有意義的價值對象。

好處是數據訪問查詢更簡單和更可重用(尤其是如果您將它們封裝在DAO/Repository Finder方法中)。再往返數據庫不應該導致任何明顯的性能影響。

+1

謝謝,除了這種方式我沒有得到沒有參與指定用戶的組。 – ChambreNoire

+0

我手上沒有dbms,但是做一個左連接作爲你的用戶id的例子應該仍然只給你參與者的組合,不是嗎?你要求「給定的用戶,給定的參與」,讓你參與沒有用戶是與你的要求矛盾。無論如何,嘗試'從參與p離開加入p.user u其中u.id =:userid或u爲null' –

+0

唉我想我誤解了你問的東西。你真的希望所有的團體都適合?無論如何iirc,HQL都支持Right Join,所以你可以從參與權開始加入p.group? –