mapstruct集合中的服务映射

时间:2018-04-25 07:48:03

标签: collections nested mapping mapstruct

我的父母有一系列我要映射的孩子。

Parent -> Collection<Child> children
ParentDTO -> Collection<ChildDTO> childDTOs

从DTO到域我想要一个数据库查询调用:我有一个服务方法可以在其上查找一个孩子的id:

Child getChild(Long id)

现在在父dtoToDomain(parentDTO)中,我希望mapstruct能够对集合中的每个项目进行查找。

此解决方案适用于single-occ,mapstruct可以在服务中找到getChild并写入查找操作:

@Mapper(uses = ChildService.class)
public interface ParentMapper {

    @Mapping(source="child.id", target="child")
    Parent dtoToDomain(ParentDTO parentDTO);
}

但是,对于集合,我必须为集合映射指定一个特定的方法,但是我在@Mapping中放了什么?像这样的东西?

@Mapping(source="child.id", target="child")
Collection<Child> dtoToDomain(Collection<ChildDTO> children)

我不知道如何编写默认实现,因为我需要实现自动装配的服务。

我可以想象这个解决方案:一个子映射器,我用这样的查找覆盖Dto to Domain方法:

@Mapper(uses = ChildMapper.class)
public interface ParentMapper {

    Parent dtoToDomain(ParentDTO parentDTO);
}

@Mapper(uses = ChildService.class)
public interface ChildMapper {

    @Mapping(source="id", target="")
    Child dtoToDomain(ChildDTO child);
}

但目标在mapstruct中是必需的。也许我可以某种方式将整个对象指定为目标?

1 个答案:

答案 0 :(得分:1)

我认为你正在寻找Object factories

使用@ObjectFactory,您可以根据源对象为映射创建实例。

例如

public class ChildFactory {


    private final ChildService childService;

    public ChildFactory(ChildService childService) {
        this.childService = childService;
    }


    public Child createChild(ChildDto dto) {
        if (dto.getId() == null) {
            return new Child();
        } else {
            return childService.findById(dto.getId());
        }
    }
}

现在,您可以使用ChildFactory中的ChildMapper。将来可能会将工厂作为@Context传递。见#1398