在Grails3中,对于命令对象,如何不更新say password字段?

在Grails3中,对于命令对象,如何不更新say password字段?,grails,Grails,如果您有一个简单调用User.save()的服务方法save(User User),如果用户说编辑了他的地址,您如何阻止它用空值覆盖密码(如果为空,则验证失败)?密码不会发送到更新视图。在过去,我们曾经有过这样的事情: def update(Map params) { params.remove("password") player.properties = params player.save() } 现在我们有了这个: interface IUserServi

如果您有一个简单调用User.save()的服务方法save(User User),如果用户说编辑了他的地址,您如何阻止它用空值覆盖密码(如果为空,则验证失败)?密码不会发送到更新视图。在过去,我们曾经有过这样的事情:

def update(Map params) {
    params.remove("password")
    player.properties = params
    player.save()
}
现在我们有了这个:

   interface IUserService {
      User get(Serializable id)
      List<User> list(Map args)
      Long count()
      void delete(Serializable id)
      User save(User user)
      User update(User user)
   }

@Service(User)
@Transactional
abstract class UserService implements IUserService {
    @Override
    User update(User user) {
        user.save() // this will overwrite the password, or fail if the password is null.
}
接口服务{
用户获取(可序列化id)
列表(映射参数)
长计数()
作废删除(可序列化id)
用户保存(用户)
用户更新(用户)
}
@服务(用户)
@交易的
抽象类UserService实现了IUserService{
@凌驾
用户更新(用户){
user.save()//这将覆盖密码,如果密码为空,则会失败。
}

params.remove的新等价物是什么?我们如何在更新对象时不更新密码?我想我们可以从数据库中读取当前密码,并在保存之前将其分配给传入的对象,但这是另一次读取。或者我们可以编写一些自定义sql,更新每个字段,但不更新我们要屏蔽的字段?

Y您可以使用
bindable
约束将属性配置为不参与批量属性绑定

class User {
    String username
    String password

    static constraints = {
        password bindable: false
    }
}

现在,数据绑定器将在数据绑定过程中排除
password
属性,您可以决定何时/是否更新该属性。您可以执行类似于
per.password=params.password
(或类似操作)每当您想更新密码时。

第一位看起来像是直接向上的参数,第二位绑定到物理用户对象,看起来更像是一个典型的rest接口。您直接保存对象,所以第一种方法是保存和分配用户以及一些不包含密码的验证bean对象,或者构建一个不包含密码的映射拥有密码,它将变成
User save(User-User,UserBean-UserBean)
然后
User update(User-User,UserBean-UserBean){User.properties=UserBean.loadValues()//这将加载您希望保存的数据的映射User.save()}
但我想知道这是否是一种特殊情况,通常情况下,您会希望保存所有内容,只有在这种情况下,如果它工作不一样,并且为了攻击行为,您可以为密码设置自己的setter`void setPassword(String pass){//do nothing}void setRealPassword(String pass){this.password=pass}`如果您的标准更新密码调用不起任何作用,那么当您需要更新密码时,您可以在对象中调用特殊的setRealPassword。这并不是您真正要求的,但仅供参考……将域类用作命令对象并不是很好的做法,因为这会导致数据库交互发生在可能不应该发生的地方。更好实践是让所有数据库交互都在事务性服务中进行。在某些情况下,将域类用作命令对象是可以的,但这在很大程度上被误解了,我有点遗憾,我们为此添加了支持。仅我的2美分。这看起来很有用,谢谢。对于create,我想设置一个密码,但是我可以使用你的params选项。太好了。我在介绍了
bindable
后不久就写了它。请参阅。