如何仅更新/保存更改的字段

Posted

技术标签:

【中文标题】如何仅更新/保存更改的字段【英文标题】:How to update / save only changed fields 【发布时间】:2012-07-27 15:10:26 【问题描述】:

如何使用 Play 仅将一组特定字段更新到数据库中?目前我有一个包含特定字段的User 模型,我们称之为:isAdministrator

private boolean isAdministrator;

我有访问器方法:

/**
 * @return the isAdministrator
 */
public boolean isAdministrator() 
    return isAdministrator;


/**
 * @param isAdministrator
 *            the isAdministrator to set
 */
public void setAdministrator(boolean isAdministrator) 
    this.isAdministrator = isAdministrator;

但是当我通过不包含isAdministrator 的表单更改用户名时,Play 会重置我的用户对象并为此用户设置值0

那么,我怎样才能只更新更改的字段?

【问题讨论】:

也许你会在这次讨论中找到一些结论:groups.google.com/forum/#!msg/play-framework/jYNlO5vDn7A/… 【参考方案1】:

我不直接回答您的问题,但我不会使用布尔值指示您的用户是否是管理员,而是创建一个继承自用户的 Admin 类。

public class Admin extends User 
....

这是SOLID 的“S”;-)

编辑:

在控制器中,您可以在使用表单值更新之前从数据库中加载旧值:

...
User userFromDB = User.findById(anId);
User userFromForm = userForm.get();

// set previous value
userFromForm.setArchived(userFromDB.getArchived());

User.update(userFromForm);
...

【讨论】:

是的,我目前正在这样做 :-),但我仍然有一个名为 isArchived 的字段。所以还是需要这个:-) isArchived 字段位于User 级别?为什么不将其添加到您的表单中?或者您也可以在使用表单值更新之前从数据库加载旧值(请参阅我的编辑)。 我不想将它添加到表单中,因为这是用户自己,正在更改他的个人资料。将自己标记为已归档是很愚蠢的:-)。看起来解决方案是一个单独的 POJO 表单,但为什么 Ebean 会这样做呢?为什么不只更新更改的字段? 您不必在 html 表单中添加它。 我不明白:你说将它添加到for中,而不是在HTML中?您建议,只有解决方案看起来像在保存之前从数据库中获取对象。【参考方案2】:

除了 nico 的 回答之外,我只能补充一点,您不需要在每种情况下都使用 Form 类。有时只需从请求中获取数据并手动更新您的对象就足够了,这在您有详细的中间保存级别时尤其适用于 ajax 调用(请参阅DynamicForm 的使用示例,它可以更短,也可以更短you can validate it yourself:

public static Result updateName(Integer id)
    User user = User.find.byId(id);
    user.name = form().bindFromRequest().get("name");
    user.update(id);
    return ok();

【讨论】:

【参考方案3】:

您可以指定要更新的字段。假设你想更新 name 那么你会这样做:

Ebean.update(user, new HashSet<String>(Arrays.asList("name")));

【讨论】:

以上是关于如何仅更新/保存更改的字段的主要内容,如果未能解决你的问题,请参考以下文章

Django:仅更新UpdateView中已更改的字段

每次输入更改后,纱线开始更新我的开发服务器,而不是仅在我保存之后

EBeans 更新不保存更改的字段项

Django Model Formset:仅跟踪集合中已更新/保存的那些项目的更改?

onAppear 不允许保存/更新选择器值的更改?

Access 2010 VBA 不保存对字段的更改