使用findAllBy时返回唯一结果

时间:2011-08-30 22:42:02

标签: grails groovy gorm

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

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_ADMINROLE_OWNER)时,如果前面提到的两个角色都作为参数给出,则该用户在集合中存在两次。有什么干净的方法我可以使集合只包含独特的结果吗?

2 个答案:

答案 0 :(得分:13)

可以在此处找到与您类似的问题:GORM createCriteria and list do not return the same results : what can I do?

方法1

如果您想直接从数据库查询中返回唯一的用户列表,那么您可以listDistinct使用User(假设该用户与rolesUserRoles OneToMany关联)

User.createCriteria().listDistinct {
    roles {
       in 'role', [role1, role2, role3]
    }
}

方法2

您还可以尝试直接查询UserRole并使用groupProperty按用户分组(请参阅http://www.grails.org/doc/latest/ref/Domain%20Classes/createCriteria.html

方法3

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

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

答案 1 :(得分:2)

查找程序将返回List,并且调用.user也会返回List,但您可以作弊并将其转换为Set,它将删除重复项。由于不需要订单(您正在返回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
}

这假设您的equals课程中定义明确hashCodeUser,因此唯一性检查有意义。