【问题标题】:Return unique results when using findAllBy使用 findAllBy 时返回唯一结果
【发布时间】:2011-11-07 05:11:02
【问题描述】:

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

【问题讨论】:

    标签: grails groovy grails-orm


    【解决方案1】:

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

    方法一

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

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

    方法二

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

    方法3

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

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

    【讨论】:

    • 方法 3 非常适合我的目的,尽管我确实删除了 * (为什么你有 * 无论如何)。发帖前我在API中搜索过这样的方法,但只找到this。非常感谢。
    • * 是扩展运算符 (groovy.codehaus.org/Operators),它是 collect 的快捷方式,例如:object*.method()object.collect{ it.method()} 相同。 Groovy 有另一个快捷方式,很多人不知道如果你不调用方法,而是调用属性,你不需要扩展运算符(所以roleList.user 将获得所有用户角色,但roleList.getUser() 会在没有展开运算符的情况下失败)。如果您和其他将阅读代码的人知道发生了什么,则可以省略它,否则,将其保留在其中更为惯用。
    【解决方案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
    }
    

    这假定您在 User 类中有明确定义的 equalshashCode,因此唯一性检查是有意义的。

    【讨论】:

    • 这是一个不错的技巧,但如果我的结果按顺序排列就好了。当您谈论“定义明确的等于和哈希码”时,我也不确定您的确切含义,但我想知道:) 现在我正在使用unique(),它似乎可以满足我的要求。感谢您的意见!
    猜你喜欢
    • 2017-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-12
    • 1970-01-01
    • 2015-10-30
    • 2020-09-09
    • 1970-01-01
    相关资源
    最近更新 更多