如何在 Hibernate 中为加入的集合指定“NOT IN”

Posted

技术标签:

【中文标题】如何在 Hibernate 中为加入的集合指定“NOT IN”【英文标题】:How to specify "NOT IN" for a joined collection in Hibernate 【发布时间】:2017-02-06 06:45:02 【问题描述】:

我有以下对象:用户和角色

我的数据库中有一个名为 user_role 的链接表,它创建了一个多对多关系,授予任何用户任何角色。在我的 java 对象上,这种关系以这样一种方式映射,即用户有一个名为角色的集合,它是角色类型的列表。

我有一个按角色搜索用户的服务。这很简单。

"select * from User u join u.roles as role where role.id in (:theRoleIWant)"

效果很好。但是现在我想返回一个没有角色的用户列表。

例如,基本级别用户的角色为 6,管理用户的角色为 3。用户可以同时拥有这两个角色,但对于我的查询,我只对没有角色 id 3 的基本级别用户感兴趣。所以我这样做:

"select * from User u join u.roles as role where role.id in (6) and role.id not in (3)"

这将继续返回同时具有这两个角色的用户。我这里有什么遗漏吗?

感谢您的宝贵时间, 玛格丽特

【问题讨论】:

【参考方案1】:

因为您从“NOT IN”中排除的不是“用户”而是“角色”。所以用户仍然显示在该查询中。

想象一下,当您加入时,您有角色 1 和 2 的用户 A,这将变成两行。因此,如果您使用“ROLE.ID NOT IN 1”,您仍然有一行用户 A 具有角色 2。

【讨论】:

【参考方案2】:

感谢 Angga,我能够对查询采取完全不同的方法。这就是我最终得到的结果:

select * from User u join u.roles as role where role.id in (:theRoleIWant) 
and not exists (select 1 from User inner_u join inner_u.roles as inner_role where inner_role.id in (:theRolesIWantToAvoid) and inner_u.id = u.id)

Annga 我将您的答案标记为正确,因为它帮助我找到了我需要的实际语法。

【讨论】:

以上是关于如何在 Hibernate 中为加入的集合指定“NOT IN”的主要内容,如果未能解决你的问题,请参考以下文章

如何在 IBM Watson Discovery 的新闻集合中为 publication_date 指定日期范围?

Hibernate多对多映射关系

渴望在 Hibernate 中使用 ScrollableResults 获取集合

如何在 JSTL 中为数组指定 useBean 标签

如何在hibernate中为count(*)编写查询

如何在 Hibernate 中为某些实体禁用模式验证?