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()