Grails 使用findAllBy时返回唯一结果

Grails 使用findAllBy时返回唯一结果,grails,groovy,gorm,Grails,Groovy,Gorm,我在服务中有以下方法,请注意def usersByRole行上的.user: def getUsersByRole(String desiredRole1, String desiredRole2, String desiredRole3) { Role role1 = Role.findByAuthority(desiredRole1) Role role2 = Role.findByAuthority(desiredRole2) Role role3 = Role.f

我在服务中有以下方法,请注意
def usersByRole
行上的
.user

def getUsersByRole(String desiredRole1, String desiredRole2, String desiredRole3) {
    Role role1 = Role.findByAuthority(desiredRole1)
    Role role2 = Role.findByAuthority(desiredRole2)
    Role role3 = Role.findByAuthority(desiredRole3)
    def usersByRole = UserRole.findAllByRoleInList([role1, role2, role3]).user
    return usersByRole
}  

它工作得很好,但是当一个用户有多个角色(即
ROLE\u ADMIN
ROLE\u OWNER
)时,如果前面提到的两个角色都作为参数给出,则该用户在集合中存在两次。有什么干净的方法可以使集合只包含唯一的结果吗?

查找程序将返回一个
列表,并调用
。用户
也将返回一个
列表,但您可以欺骗并将其强制转换为
,它将删除重复项。由于不需要订单(您返回的是
def
,因此您似乎并不关心集合类型),因此不需要将其转换回:

def getUsersByRole(String desiredRole1, String desiredRole2, String desiredRole3) {
    Role role1 = Role.findByAuthority(desiredRole1)
    Role role2 = Role.findByAuthority(desiredRole2)
    Role role3 = Role.findByAuthority(desiredRole3)
    return UserRole.findAllByRoleInList([role1, role2, role3]).user as Set
}

这假定您在
User
类中有一个定义良好的
equals
hashCode
,因此唯一性检查是有意义的。

这里可以找到与您类似的问题:

方法1 如果您想直接从DB查询返回唯一的用户列表,那么您可以在
User
上使用
listdinct
(假设该用户与
UserRoles
OneToMany关联)

方法2 您还可以尝试直接查询
UserRole
,并使用
groupProperty
按用户分组(请参阅)

方法3 从返回的列表中删除重复的用户:

UserRole.findAllByRoleInList([role1, role2, role3])*.user.unique()

方法3对我来说非常有用,尽管我确实删除了
*
(你到底为什么在那里有
*
)。在发布之前,我在API中搜索了这样一个方法,但只找到了。非常感谢。
*
是扩展运算符(),它是
收集
的快捷方式,例如:
对象*.method()
对象.收集{it.method()}
相同。Groovy还有另一个快捷方式,很多人不知道如果不调用方法,而是调用属性,那么您不需要spread操作符(因此
roleList.user
将获得所有角色的所有用户,但是
roleList.getUser()
将在没有spread操作符的情况下失败)。如果您和其他将阅读代码的人知道发生了什么,您可以忽略它,否则,将其保留在其中更为惯用。这是一个很好的技巧,但将我的结果按顺序排列会很好。我也不知道你说的“定义良好的equals和hashCode”到底是什么意思,但我想知道:)现在我正在使用
unique()
,它似乎做了我想做的事情。谢谢你的意见!
UserRole.findAllByRoleInList([role1, role2, role3])*.user.unique()