如何仅更新已更改的属性 - Spring MVC

mel*_*kir 11 java model-view-controller spring

我的控制器

@RequestMapping(value = "/user/{id}", method = RequestMethod.GET)
public String updateUserById(@PathVariable("id") Long id, Model model) {
    User user = userRepository.findOne(id);
    model.addAttribute(user);
    return "admin/editUser";
}

@RequestMapping(value = "/user/{id}", method = RequestMethod.POST)
@ResponseBody
public String updateUserById(@PathVariable("id") Long id, @ModelAttribute User user) {
    userRepository.updateUser(id, user); // with a try catch
}
Run Code Online (Sandbox Code Playgroud)

@Override
public void updateUser(Long id, User user) {
    User userDB = userRepository.findOne(id);
    userDB.setFirstName(user.getFirstName());
    userDB.setLastName(user.getLastName());
    userDB.setEmail(user.getEmail());
    userDB.setUsername(user.getUsername());
    userRepository.save(userDB);
}
Run Code Online (Sandbox Code Playgroud)

这种方法有效但对我来说非常难看.假设用户刚刚更改了视图中的firstname字段,如何调整我的代码只调用函数来设置firstname?

像Observer模式通知字段有变化?

Pat*_*ick 1

我想你的代码是这样工作的:

一个用户想要改变他的一些数据user entity。意味着在前端你已经向他展示了数据库用户表中的所有条目,如名字、姓氏等。

例如,用户更改了他的名字并点击了保存按钮。您的控制器接收用户实体,包括 user.id、新的名字和所有旧的设置值。如果您的代码像这样工作,您可以轻松地获取save()用户实体。无需先从数据库中获取用户。

所以就这样做:

@Override
public void updateUser(User user) {
    userRepository.save(user);
}
Run Code Online (Sandbox Code Playgroud)

他们Repository知道用户实体的 Id,并且只更新完整的实体。

由于您的用户实体中没有 Id,请使用控制器中的 Id,如下所示:

@Override
public void updateUser(User user, Long Id) {
    user.setId(Id);
    userRepository.save(user);
}
Run Code Online (Sandbox Code Playgroud)

  • 它没有回答问题。问题是:“如何仅更新已更改的属性”。答案是,仍然更新 userRepository.save(...) 内的属性。它只是不执行设置,但在幕后会发生对数据库的设置。示例:user.firstName = 'lolo',用户想要更改user.lastName='koko'。但@trudy 拦截它并更改了名字。此次更新将改变两者 (3认同)
  • @Patrick问题背后的想法不是代码约定,而是数据完整性。 (3认同)