Spring Data JPA:如何优雅地更新模型?

时间:2015-08-02 03:28:47

标签: spring spring-mvc spring-boot spring-data spring-data-jpa

  1. 我的模型是这样的:

    @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
    }
    
  2. 我们通过http请求收集表单或移动数据,springmvc会将这些数据发送给像用户这样的模型。

    例如,我有这样的请求:

    http://localhost:8080/update?id=1919&email=xx@google.com

  3. 在控制器中
  4. ,请求网址及其参数将自动转换为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);
    }
    
  5. 如果我在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,但我不会想要更新此字段,我只想更新电子邮件字段。

  6. 我有两种方法可以解决问题,但所有这些方法都不优雅。

    5.1首先加载用户对象并更新

    User userExist = userRepository.findOne(user.getId());
    userExist.setEmail(user.getEmail());
    
    //or using 
    //BeanUtil.copyProprty(formDto,modle)
    
    userRepository.save();
    

    5.2使用@DynamicUpdate,但它不起作用。

    是否有其他方法可以更新用户模型,而不需要做额外的工作。

    提前致谢。

3 个答案:

答案 0 :(得分:13)

最简单的方法是适当设置控制器方法:

@RequestMapping(value = "/users/{user}", method = RequestMethod.PATCH)
public … updateUser(@ModelAttribute User user) { … }

根据reference documentation调用此方法时,会发生以下步骤:

  1. 需要获取User的实例。这基本上需要在ConverterString User向Spring MVC注册,以将从URI模板中提取的路径段转换为User。如果你是使用Spring Data并按其reference documentation中所述启用其Web支持,这将开箱即用。
  2. 获取现有实例后,请求数据将绑定到现有对象。
  3. 绑定对象将被移交给方法。
  4. 其他提示

    • 不要使用GET作为HTTP方法进行更新。 GET被定义为安全操作(无副作用),更新不是。 PATCH是正确的方法,因为它被定义为允许对现有资源进行部分更新。
    • 要将表单数据提交到PUTPATCH个请求,您需要在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/updateEmailhttps://server/updateWeblink
  • 更改您的UserRepository.save()方法,不要使用空字段更新数据库数据,例如if (webObject.getField() != null) dbObject.setField(webObject.getField())