我如何基本上对字符串数据类型字段执行唯一约束。
class User{
String username
String Email
static hasMany = [roles:Roles]
static constraints = {
Email(email:true)
username(unique:true)
}
}
有没有简单的方法来实现username(unique: true)
或者我必须使用.findByNameLike
等方法手动检查数据库吗?
用户名应该是唯一的,但唯一性应该是不区分大小写的。
答案 0 :(得分:13)
因此,如果您希望拥有唯一且不区分大小写的用户名,则有两种可能的方法。
简单的一个:
或者,关于性能,更贵:
现在取决于,如果您只是想让用户自由地输入他想要的用户名(第一种可能性),或者您想保留用户名案例以显示原因(第二种可能性)。
你的问题听起来像是第二个,所以自定义验证器看起来像这样:
class User {
String username
String email
static hasMany = [roles:Roles]
static constraints = {
email(email:true)
username(validator: {
return !User.findByUsernameILike(it)
})
}
}
希望有所帮助。
[编辑]
正如海因里希在评论中所述,上述验证器会在用户更改用户名时出现问题。
快速&很脏,但我认为这解决了这个问题:
username(validator: { val, obj ->
def similarUser = User.findByUsernameILike(val)
return !similarUser || obj.id == similarUser.id
})
注意,它没有经过测试,我不确定你是否能够在验证器中定义变量。
Meta:我绝不会让用户更改用户名;)
答案 1 :(得分:2)
为了添加@air_blob“快速而肮脏”的解决方案的另一个解决方案,你试过吗?
username(validator: { val, obj ->
return !User.findByUsernameIlikeAndIdNotEqual(val, obj.id)
})
答案 2 :(得分:1)
username(unique:true)
是一个有效的约束。
要使约束不区分大小写,您需要编写自定义验证程序。有关详细信息,请参阅this discussion thread。