我的模型是这样的:
@Entity @Table(name = "user") public class User { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; @Column(name="email") private String email; @Column(name = "weblink") private String webLink; //getter & setter }
我们通过 http 请求收集表单或移动数据,springmvc 会将这些数据提供给 Model 类用户。
例如,我有一个这样的请求:
http://localhost:8080/update?id=1919&email=xx@google.com
在contoller中,请求url及其参数会自动转成
User
对象。@RequestMapping(method = RequestMethod.GET, value = "/update0") public User update(@ModelAttribute("User") User user){ System.out.println(user.getId()); System.out.println(user.getEmail()); System.out.println(user.getWebLink()); return userRepository.save(test); }
如果我在mysql中有一条id为1919的记录,并且列(id、email、weblik)都有值。
如你所见,通过 web 或 mobile 传递的用户对象有两个属性
http://localhost:8080/update?id=1919&email=xx@google.com
id 和 email 有值,而 weblink 没有。
所以,如果我执行
save
方法,列 email 将更新为xx@google.com
,weblik 字段也将更新为NULL
,但是我不想更新这个字段,我只想更新email字段。我有两种方法可以解决这个问题,但都不是优雅的。
5.1 先加载用户对象并更新
User userExist = userRepository.findOne(user.getId()); userExist.setEmail(user.getEmail()); //or using //BeanUtil.copyProprty(formDto,modle) userRepository.save();
5.2 使用
@DynamicUpdate
,但它不起作用。有没有其他方法可以更新用户模型并且不做一些额外的工作。
提前致谢。
最佳答案
最简单的方法是适当设置 Controller 方法:
@RequestMapping(value = "/users/{user}", method = RequestMethod.PATCH)
public … updateUser(@ModelAttribute User user) { … }
根据reference documentation调用此方法时会发生以下步骤:
- 需要获取一个
User
的实例。这基本上需要将String
到User
的Converter
注册到 Spring MVC 中,以便将从 URI 模板中提取的路径段转换为用户
。如果你是例如使用 Spring Data 并启用其 Web 支持,如其 reference documentation 中所述,这将开箱即用。 - 获取现有实例后,请求数据将绑定(bind)到现有对象。
- 绑定(bind)的对象会被交给方法。
其他提示
- 不要使用
GET
作为 HTTP 更新方法。GET
被定义为安全操作(无副作用),而更新则不是。PATCH
是正确的方法,因为它被定义为允许对现有资源进行部分更新。 - 要将表单数据提交到
PUT
和PATCH
请求中,您需要向应用程序注册一个HttpPutFormContentFilter
,如 here 所述.我提交了 issue with Spring Boot默认注册。
关于 Spring 数据 JPA : How to update a model elegantly?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31768289/