【问题标题】:Spring boot: Custom mapping between DTO and Entity using ModelMapperSpring boot:使用 ModelMapper 在 DTO 和 Entity 之间自定义映射
【发布时间】:2021-11-17 13:39:50
【问题描述】:

我想将我的 DTO (CreateOrUpdatePostRequest) 映射到我的实体 Post

但我不知道该怎么做,因为我的实体有这样的关系:

@Entity
@Table(name = "POSTS")
@Data
public class Post {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "post_id")
    private int id;

    private String title;

    private String description;

    @Temporal(TemporalType.DATE)
    @Column(name = "expire_at")
    private Calendar expireAt;

    @ManyToOne
    @JoinColumn(name = "CATEGORY_ID")
    private Category category;

    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "TAG_POST", joinColumns = { 
            @JoinColumn(name = "post_id", nullable = false, updatable = false) }, 
            inverseJoinColumns = { @JoinColumn(name = "tag_id", 
                    nullable = false, updatable = false) })
    private Set<Tag> tags = new HashSet<Tag>(0);
}

一篇文章可以有一个类别和多个标签。

这是我的 DTO:

@Data
public class CreateOrUpdatePostRequest {
    @NotNull
    @Size(min = 10, max = 30)
    private Sting title;

    @NotNull
    @Size(min = 50, max = 600)
    private String description

    @NotNull
    @ValidDateString
    private String expireAt;

    @NotNull
    private Category category;

    @NotNull
    private List<TagDTO> tags;

    public List<Integer> getTagIds() {
        return this.getTags().stream().map(TagDTO::getId).collect(Collectors.toList());
    }
}

问题:我的问题是我必须为某些属性应用特定的映射逻辑,以确保标签有效,例如:

post.setTags(tagService.findAllByIds(request.getTagIds()));
  1. 所以我想应该在我的PostService 中完成映射,知道我必须访问tagService?我的意思是我不能真正在我的CreateOrUpdateRequest 中创建toEntity 方法。

  2. 有没有办法保留所有属性的默认 ModelMapper 行为,但使用外部服务为某些属性指定特定行为?

  3. 如果我的 DTO 内部有一个 DTO 需要与上述相同的行为,例如在 TagDTO 中,如何继续?

【问题讨论】:

  • 只需创建类/服务,它将您的 dto 转换为实体,或在实体内添加一个函数,该函数可以基于 DTO 创建此实体(可能类似于构建器类或其他东西)

标签: java spring modelmapper


【解决方案1】:

我不确定你是否已经经历过 MapStruct 的事情,但你可以在这里详细看看。

https://medium.com/uphill-engineering-design/deep-dive-into-mapstruct-spring-7ddd8dac3d6d

【讨论】:

  • 我必须研究所有这些,因为我知道我在一个非常大的实体上这样做。您将映射器存储在代码中的什么位置?我说的是代码组织。在新的 Mapper 包中?
  • 是的,他们可以有自己的包
  • 好的,谢谢。如果我理解正确,MapStruct 依赖于接口来生成将我的 DTO 转换为实体的类。所以我很难有像我的服务示例那样的特定行为?
  • 是的,但是你可以随意覆盖行为,你会在我分享的文章中找到它
  • 是的,我看到了链接。但是,例如,我是否可以使用相同的 MapStruct 来添加实体,以及使用相同但忽略 null 属性来更新实体。我正在尝试做一个 CRUD。
【解决方案2】:

这是基于边界的意见,但仍然是我对此的看法:

  1. 我猜你的 PostService 是 Spring 管理的 Bean(可能用 @Service 注释),所以我会说应该在那里完成映射,使用 TagService 来获得 Tags。李>
  2. 我不是任何映射器库的忠实拥护者,因为一旦使用 Spring,您的代码中就已经有了足够的魔力。话虽如此,我更喜欢明确并自己映射模型。在此过程中,您拥有充分的灵活性。
  3. 我会说TagDto 应该由TagService 映射。

【讨论】:

    猜你喜欢
    • 2019-01-15
    • 2021-01-08
    • 2021-03-13
    • 2013-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-08
    • 1970-01-01
    相关资源
    最近更新 更多