java - 在实体和 DTO 之间映射非空字段的最佳方法是什么?

标签 java spring-boot jpa mapping dto

我正在使用 HTTP PATCH 方法来编辑 JPA 实体。由于这是 PATCH,因此只会编辑那些未设置为空的字段。在 DTO 和实体之间仅映射非空字段的最佳方法是什么?给定的实体可能有多个字段 - 比如说 20 个或更多,所以我不想这样做:

if(dto.getFoo() != null) {
   entity.setFoo(dto.getFoo);
}

这种映射有什么智能机制吗?

我正在使用 springboot:1.5.6.RELEASE

最佳答案

Blaze-Persistence Updatable Entity Views 将是您正在寻找的更智能的解决方案;) Blaze-Persistence是我工作的基于 JPA 的库。你的用例应该已经得到支持,虽然我还没有很好的 Spring WebMvc 集成,所以你现在必须自己做一些管道。不过,我对此有一些想法,这只是时间问题和感兴趣的各方,直到集成更加顺利。

可更新的实体 View 允许映射实体的子集,并且也只刷新该子集。由于使用脏跟踪,它确切地知道发生了什么变化,从而允许进行细粒度的刷新。

所以 PATCH 支持的想法是通过对象的 id 获取一个空引用。为空意味着它没有数据,即所有空值。脏跟踪假定初始状态为空。您可以简单地将请求有效负载映射到此对象,如果值为空,它不会将其识别为已更改,因此将其忽略。如果设置了任何非空值,它会确定这样的字段是脏的并且在刷新时,只会刷新脏值。

我自己还没有尝试过,但是你可以这样做

// Create reference for the id, the object is empty i.e. all null except for the id
MyDto dto = entityViewManager.getReference(MyDto.class, someId);
// Map the payload on the DTO which will call setFoo(null) but that's ok, because that isn't considered being dirty
jsonMapper.map(requestPayload, dto);
// Flush dirty changes i.e. non-null values
entityViewManager.update(entityManager, dto);

使用PARTIAL刷新模式时执行的更新查询将只包含具有非空值的属性的集合子句。 DTO 看起来像这样

@EntityView(MyEntity.class)
@UpdatableEntityView(mode = FlushMode.PARTIAL)
public interface MyDto {
  @IdMapping Integer getId();
  String getFoo();
  void setFoo(String foo);
}

如果没有脏东西,它甚至不会执行查询。

关于java - 在实体和 DTO 之间映射非空字段的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49740564/

相关文章:

java - 如何在 SaveAll() 之前关闭选择?

java - 我应该如何使用 jTable 来表示对象列表?

java - HBase-0.90.6 在 hbase-site xml 文件中的 Window 7 错误配置

Java react 器通量未根据预期进行映射

java - 存在原始打字问题

java - Hibernate @Id 通过继承

java - SSLContext.getInstance 中使用的协议(protocol)是什么

java - jfilechooser,保存多个文件,图像?

java - 如何使用Spring正确获取用户列表?

java - Spring boot 将 JSON 反序列化为多态类型