Cha*_*ire 5 java sql hibernate join 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;
}
Run Code Online (Sandbox Code Playgroud)
所以
参与-->1组
和用户 1<-->N 参与
对于给定的用户,我如何检索所有具有关联参与的组(或 null 表示没有参与)?我一直在玩连接提取,但到目前为止无济于事......
非常感谢,
中国网
附注。因此,我可以在 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;
Run Code Online (Sandbox Code Playgroud)
(可能是 HQL 本身中的一些错字,但这个想法应该是正确的)
根据您的 SQL 和描述,您要问的是基于 找出所有Participation(及其对应的Group)User,这只是
select p.id, p.group.id from Participation p where p.user.id = :userId
Run Code Online (Sandbox Code Playgroud)
为了使它更好,您应该取而代之的是获取实体:
from Participation p left join fetch p.group where p.user.id = :userId
Run Code Online (Sandbox Code Playgroud)
在理解您想要做什么时存在一些混淆:您想要所有组(无论条件如何)。而且,对于给定的用户,您希望找到该用户所涉及的所有组和参与。
虽然使用 Right-outer-join 应该是可能的:
select g, p from Participation p
right outer join p.group g
where p.user.id=:userId
Run Code Online (Sandbox Code Playgroud)
或者,在更高版本的 Hibernate (>= 5.1 ?) 中,它允许显式连接(之前没有尝试过,您可以尝试一下)(如果您使用的是 JPQL with,on则替换为):
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
Run Code Online (Sandbox Code Playgroud)
或者您可以使用其他技术,例如子查询等。但是,在您的情况下,我宁愿将它们分成更简单的查询,并在您的代码中进行简单的聚合。
基本思想是有
from Groupsfrom Participation p join fetch p.group where p.user.id=:userId然后您可以轻松地将它们聚合为您想要的形式,例如Map<Group, List<Participation>>,甚至更有意义的值对象。
好处是数据访问查询更简单且更可重用(尤其是如果您将它们包装在 DAO/Repository finder 方法中)。再一次到 DB 的往返不应该在这里造成任何明显的性能影响。
Dhe*_*rik -1
您需要映射实体participation中的关系Group。Participation如果和之间的关系Group是 1..N:
class Group {
String id
List<Participation> participations
}
Run Code Online (Sandbox Code Playgroud)
JPQL 可以是:
SELECT g.id, p.id FROM Group g
JOIN g.participations p
JOIN p.user user
WHERE user.id = :idUser
Run Code Online (Sandbox Code Playgroud)
您可以接收此信息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
Run Code Online (Sandbox Code Playgroud)
但你不能LEFT JOIN使用这个策略。上面的查询行为就像JOIN.
在 Hibernate 中,您映射想要进行查询的关系的一侧是正常的。因此,我推荐第一种方法,映射关系。
| 归档时间: |
|
| 查看次数: |
26801 次 |
| 最近记录: |