[英]How to map entity and list of entities to a single DTO with nested list by using MapStruct?
I need to convert some entity and list of entities to a single DTO by using MapStruct .我需要使用MapStruct将一些实体和实体列表转换为单个 DTO。 This DTO includes nested list.此 DTO 包括嵌套列表。
Let's say, I have the following persistence-backed POJO:比方说,我有以下持久性支持的 POJO:
public class Entity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "name", nullable = false)
private String name;
// SKIPPED
@OneToOne(mappedBy = "entity", cascade = CascadeType.ALL)
private EntityMetadata entityMetadata;
}
And some collection of this entities:以及这些实体的一些集合:
List<Entity> entities
DTO is presented below: DTO 介绍如下:
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class ScreenDocumentDto { // dto
private Long id;
private String name;
List<SomeLinkDto> someLinks;
}
And nested DTO:和嵌套的 DTO:
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class SomeLinkDto {
private Long id;
private ZonedDateTime someDate;
}
All the fields except the someLinks list I need to map from entity:除了我需要从实体映射的 someLinks 列表之外的所有字段:
dto.setId(entity.getId());
dto.setName(entity.getName());
// SKIPPED
Nested list I populate as follows:我填充的嵌套列表如下:
List<SomeLinkDto> someLinks = new ArrayList<>(entities.size());
for (Entity entity : entities) {
someLinks.add(SomeLinkDto.builder().id(entity.getId())
.someDate(entity.getEntityMetadata().getSomeDate()).build());
}
The result involves a lot of manually transformations:结果涉及到很多手动转换:
@Mapper(componentModel = "spring")
public interface ScreenDocumentMapper extends BaseMapper<Entity, ScreenDocumentDto> {
default ScreenDocumentDto toScreenDocumentDto(List<Entity> entities, Entity entity) {
ScreenDocumentDto dto = new ScreenDocumentDto();
List<SomeLinkDto> someLinks = new ArrayList<>(entities.size());
for (Entity entity : entities) {
someLinks.add(SomeLinkDto.builder().id(entity.getId())
.someDate(entity.getEntityMetadata().getSomeDate()).build());
}
dto.setId(entity.getId());
dto.setName(entity.getName());
...
dto.setSomeLinks(someLinks);
return dto;
}
// SKIPPED
Is there a way to do the same job by using features of MapStruct?有没有办法通过使用 MapStruct 的功能来完成同样的工作? Like that:像那样:
@Mapper(componentModel = "spring")
public interface ScreenDocumentMapper extends BaseMapper<Entity, ScreenDocumentDto> {
@Mappings({
@Mapping(source = "...", target = "..."),
...
})
ScreenDocumentDto toDto(Entity entity);
}
You can achieve the custom toScreenDocumentDto
method with MapStruct by using multiple source parameters.您可以使用多个源参数通过 MapStruct 实现自定义toScreenDocumentDto
方法。
For example例如
@Mapper(componentModel = "spring")
public interface ScreenDocumentMapper extends BaseMapper<Entity, ScreenDocumentDto> {
@Mapping(source = "entities", target = "someLinks")
ScreenDocumentDto toDto(Entity entity, List<Entity> entities);
@Mapping(source = "entityMetadata.someDate", target = "someDate")
SomeLinkDto toLinkDto(Entity entity);
}
In case the Entity
has the links as a property you can do:如果Entity
将链接作为属性,您可以执行以下操作:
@Mapper(componentModel = "spring")
public interface ScreenDocumentMapper extends BaseMapper<Entity, ScreenDocumentDto> {
@Mapping(source = "links", target = "someLinks")
ScreenDocumentDto toDto(Entity entity);
@Mapping(source = "entityMetadata.someDate", target = "someDate")
SomeLinkDto toLinkDto(Entity entity);
}
Add folowing annotation under your mapping method.在您的映射方法下添加以下注释。
@Mapping(target = "someLinks",expression = "java(Arrays.asList(new SomeLinkDTO(id,someDate)))"
And on top of mapper interface add annotation.并在映射器界面之上添加注释。
@Mapper(imports = {Arrays.class ,SomeLinkDTO.class})
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.