使用 Spring Boot 进行部分更新

问题描述 投票:0回答:1

我正在开发一个 Java Spring Boot 项目。我有一个有 20 个字段的实体。我目前有一个 put 方法,它接受这 20 个字段,所有字段都是非空值,并且我使用验证器(包括我的自定义验证器)来验证它们。但这是昂贵的。即使我想更改数据库中的单个字段,我也会完全获取该行,使用自定义映射器更新所有字段并保存到数据库中。在此实现中,即使只有一个字段发生变化,我也必须发送请求中的所有字段,并且还将 19 个未更改的字段覆盖到数据库中,这是昂贵的。我正在寻找以下解决方案:

  1. 我应该能够仅发送应该更改的字段,并且我应该能够使用验证器在 DTO 级别验证它们(例如:我应该能够检查值是否在 0 到 100 之间。在当前的实现中,我有为此的自定义验证器)
  2. 我应该能够仅将更改的字段覆盖到数据库中。我不应该覆盖应该保持不变的值。
  3. (有点可选)如果能通用就更好了。我可以轻松适应不同的控制器。

我一直在搜索Java Reflections并找到了这个实现:

    @PatchMapping("/{id}")
    public Product updateProductFields(@PathVariable int id,@RequestBody Map<String, Object> fields){
        return service.updateProductByFields(id,fields);
    }
    public Product updateProductByFields(int id, Map<String, Object> fields) {
        Optional<Product> existingProduct = repository.findById(id);

        if (existingProduct.isPresent()) {
            fields.forEach((key, value) -> {
                Field field = ReflectionUtils.findField(Product.class, key);
                field.setAccessible(true);
                ReflectionUtils.setField(field, existingProduct.get(), value);
            });
            return repository.save(existingProduct.get());
        }
        return null;
    }

public interface ProductRepository extends
        JpaRepository<Product, Integer> {


}

但我不确定这是否满足我的愿望。你有什么建议吗?

java spring postgresql spring-boot http-patch
1个回答
0
投票

我认为你应该考虑一个注释处理器。然后你可以用

Product
来注释你的
@Merger
类。

例如手动创建的

Product.java

@Merger
public class Product {
   @NotNull private Long id;
   @NotNull private String name;
}

注释处理器随后会生成

public class ProductDelta {
   private Long id;
   private String name;
}

public class ProductMerger {
   public Product merge(Product product, ProductDelta delta) { ... }
}
© www.soinside.com 2019 - 2024. All rights reserved.