【问题标题】:Official way to implements PATCH method in REST with partial update通过部分更新在 REST 中实现 PATCH 方法的官方方法
【发布时间】:2025-12-20 13:50:14
【问题描述】:

我绝对没有找到完全自动进行部分更新的明确方法(可以通过在数据库和部分对象中逐个字段对象进行比较)。

我看到了一些类似的曲目:

  • here 但我不知道它有什么魔力MapperService
  • here 但很丑,我敢肯定存在更好的解决方案
  • here 但我不知道使用 save(Map<String, Object> updates, String id) 方法的 heavyResourceRepository 存储库类型是什么
  • 或者我们可以/必须使用ModelMapper 来映射非空字段吗?
  • here覆盖copyProperty方法

谢谢,PATCH 方法可用,但我没有看到明确的方法来实现它。

【问题讨论】:

  • 我整理了一个post 在Spring 中如何使用PATCH

标签: hibernate rest spring-boot spring-rest http-method


【解决方案1】:

您可以使用 @RepositoryRestResource 为您执行此操作。

当您像这样导出端点时:

@RepositoryRestResource(path = "some_entity")
public interface SomeEntityRespostiory extends JpaRepository<SomeEntity, Integer> {

}

您将公开默认 CRUD 的所有选项,并且您将不需要控制器类。

您可以使用 PUT 替换所有实体字段。或者,您可以使用 PATCH 仅替换实体中的某些字段。

此 PATCH 方法将负责仅更新您从有效负载中实际收到的字段。

例如:

@Entity
@Getter
@Setter
@NoArgsContructor
public classe SomeEntity {

    @Id
    private Integer id;
    private String name;
    private String lastName;
    private LocalDate birthDate;
    private Integer phoneNumber;
}

给你创建你的注册:

curl -i -X POST -H "Content-Type:application/json" -d 
'{"name": "Robert", "lastName": "Downey", "bithDate": "1965-4-4", "phoneNUmber":2025550106}'
http://localhost:8080/some_entity

要替换您使用的所有记录:

curl -i -X PUT -H "Content-Type:application/json" -d 
'{"name": "Robert", "lastName": "Downey", "bithDate": "1965-4-4"}'
http://localhost:8080/some_entity/{id}

在这种情况下,变量“phoneNumber”将为空。

但是,如果你试试这个:

curl -i -X PATCH -H "Content-Type:application/json" -d 
'{"lastName": "Downey Jr.", "bithDate": "1965-4-15"}'
http://localhost:8080/some_entity/{id}

只会更新“lastName”和“birthDate”。

这太棒了,因为您不必担心。

您可以在documentation 中了解更多相关信息。搜索“补丁”这个词,你可以找到一些例子。

如果您需要进行一些验证,例如:名称至少需要三个单词。你可以像这样放置一个 EventHandler:

@Component
@RepositoryEventHandler
public class SomeEntityHandler {

    @Autowired
    private SomeEntityService someEntityService;

    @HandleBeforeCreate
    @HandleBeforeSave
    public void save(SomeEntity someEntity) {
        someEntity.verifyStringSize(someEntity.name);
    }
}

然后您可以抛出异常,或将所有字符串更改为大写字符串,或者您想要的任何其他内容。

【讨论】: