Grails GORM 约束

Grails GORM Constraint

给定以下两个域:

class Follows {
    User followee
    ...
    static belongsTo = [follower: User]
}

class User {
    String name
    String lastName
    ...
    static hasMany = [ follows: Follows ]
    static mappedBy = [ follows: 'follower' ]
}

这会创建以下 table:

+------+-------------+-------------+
|  id  | follower_id | followee_id |
+------+-------------+-------------+
| 1    | 1           | 3           |
| 2    | 3           | 2           |
| 3    | 2           | 1           |
+------+-------------+-------------+

有没有办法通过 contraints 来防止重复 follower - followee?我正在尝试阻止这两个方向,例如,如果用户 ID 1 已经在关注用户 ID 3,则用户 ID 3 不应关注 用户 ID 1。

换句话说,这就是我要阻止的:

+------+-------------+-------------+
|  id  | follower_id | followee_id |
+------+-------------+-------------+
| 1    | 1           | 3           |
| 2    | 3           | 1           |
+------+-------------+-------------+

我知道我可以在插入之前查询数据库,以检查用户 1 是否跟随 3(或相反),如果为真,则取消插入,但我试图避免两次访问数据库每关注操作。

干杯,感谢您的所有回答!

不,没有现有的约束来处理这种情况。您可以创建自己的约束,但它必须查询数据库,所以没有意义。

但是,如果您将新的 属性 添加到 Follows 并包含适用于以下两个方向的唯一值,则您 可以 使用唯一约束。

class Follows {
    User followee
    ...
    Integer someUniqueProperty

    static belongsTo = [follower: User]

    static constraints = {
        someUniqueProperty unique: true
    }

    def beforeInsert() {
        someUniqueProperty = calculateUniqueProperty()
    }

    def beforeUpdate() {
        someUniqueProperty = calculateUniqueProperty()
    }

    private Integer calculateUniqueProperty() {
       [follower.id, followee.id].sort().hashCode()
    }
}

在上面的示例中,someUniquePropertyFollows 的所有实例中必须是唯一的。通过将 followerfollowee 放在一个列表中,始终以相同的顺序,然后获取哈希码,它的值在 inserting/updating 实例之前设置。这是基于以下事实:[1, 3].hashCode() == [3, 1].sort().hashCode()

简而言之,添加唯一 属性 允许数据库强制执行您需要的约束。