我的模型是这样的:
@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会将这些数据发送给像用户这样的模型。
例如,我有这样的请求:
http://localhost:8080/update?id=1919&email=xx@google.com
,请求网址及其参数将自动转换为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)都有值。
如您所见,通过网络或移动设备传递的用户对象有两个属性
http://localhost:8080/update?id=1919&email=xx@google.com
id和email有值,而weblink没有。
因此,如果我执行save
方法,列电子邮件将更新为xx@google.com
,weblik字段也会更新为NULL
,但我不会想要更新此字段,我只想更新电子邮件字段。
我有两种方法可以解决问题,但所有这些方法都不优雅。
5.1首先加载用户对象并更新
User userExist = userRepository.findOne(user.getId());
userExist.setEmail(user.getEmail());
//or using
//BeanUtil.copyProprty(formDto,modle)
userRepository.save();
5.2使用@DynamicUpdate
,但它不起作用。
是否有其他方法可以更新用户模型,而不需要做额外的工作。
提前致谢。
答案 0 :(得分:13)
最简单的方法是适当设置控制器方法:
@RequestMapping(value = "/users/{user}", method = RequestMethod.PATCH)
public … updateUser(@ModelAttribute User user) { … }
根据reference documentation调用此方法时,会发生以下步骤:
User
的实例。这基本上需要在Converter
到String
User
向Spring MVC注册,以将从URI模板中提取的路径段转换为User
。如果你是使用Spring Data并按其reference documentation中所述启用其Web支持,这将开箱即用。GET
作为HTTP方法进行更新。 GET
被定义为安全操作(无副作用),更新不是。 PATCH
是正确的方法,因为它被定义为允许对现有资源进行部分更新。PUT
和PATCH
个请求,您需要在here所述的应用程序中注册HttpPutFormContentFilter
。我提交了issue with Spring Boot来默认注册。答案 1 :(得分:0)
首先,我需要说Patch
@Oliver Gierke
解决方案非常棒。
在我之前的项目中,我的解决方案是:
1.创建一个抽象类来实现JpaRepository
,并实现save()
函数
2.在保存功能中,从DB获取实体。它不存在,只是保存它。否则,使用反射从更新的实体获取所有NOT NULL字段,并从DB设置为实体。 (它和你一样,但是我为所有保存功能都这样做了)
答案 2 :(得分:-2)
首先,当您要更新数据时,should use HTTP POST。
其次,@DynamicUpdate
约为something else,这不是您的解决方案。它用于生成具有较少列的SQL更新语句。
您应该执行以下操作之一:
https://server/updateEmail
和https://server/updateWeblink
UserRepository.save()
方法,不要使用空字段更新数据库数据,例如if (webObject.getField() != null) dbObject.setField(webObject.getField())