我正在使用 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/