从多个源DTO映射到一个目标

时间:2018-11-05 11:07:30

标签: java mapstruct

使用MapStruct。例如:

class Dto {
    DtoA a;
    DtoB b;
}

class DtoA {
    Long id;
    //...
}

class DtoB {
    Long id;
    //...
}


class Entity {
    AB ab;
}

如何将DtoADtoB映射到AB?

我尝试过:

public abstract Entity toEntity(Dto dto);

@Mappings({
            @Mapping(source = "a", target = "ab.a"),
            @Mapping(source = "b", target = "ab.b")
)}
public abstract AB toABEntity(DtoA a, DtoB b);

已经生成了所有代码*,未调用方法toABEntity

*很糟糕,因为它先设置a,然后再设置b会创建ab的新实例,因此a丢失了。

1 个答案:

答案 0 :(得分:3)

据我了解,您想将Entity映射到Dto并将两个字段Dto.aDto.b合并到一个字段Entity.ab中。

通常,当您尝试这样做时:

@Mapper
public interface TestMapper {
    @Mappings({
        @Mapping(source = "a.id", target = "ab.aId", qualifiedByName = "toAB"),
        @Mapping(source = "b.id", target = "ab.bId", qualifiedByName = "toAB"),
    })
    Entity toEntity(Dto dto);
}

对于每个在ab内具有目标属性的@Mapping,生成的映射器将覆盖ab实例。显然,这是一个错误,并且在MapStructs GitHub上有一张票:https://github.com/mapstruct/mapstruct/issues/1148

但是有一种解决方法:

@Mapper
public interface TestMapper {
    @Mappings({
        @Mapping(source = "dto", target = "ab", qualifiedByName = "toAB"),
    })
    Entity toEntity(Dto dto);

    @Mappings({
        @Mapping(target = "aId", source = "a.id"),
        @Mapping(target = "bId", source = "b.id"),
    })
    AB toAB(Dto dto);
}

我认为AB类是:

class AB {
    public Long aId;
    public Long bId;
}

生成的映射器代码:

public class TestMapperImpl implements TestMapper {

    @Override
    public Entity toEntity(Dto dto) {
        if ( dto == null ) {
            return null;
        }

        Entity entity = new Entity();

        entity.ab = toAB( dto );

        return entity;
    }

    @Override
    public AB toAB(Dto dto) {
        if ( dto == null ) {
            return null;
        }

        AB aB = new AB();

        Long id = dtoBId( dto );
        if ( id != null ) {
            aB.bId = id;
        }
        Long id1 = dtoAId( dto );
        if ( id1 != null ) {
            aB.aId = id1;
        }

        return aB;
    }

    private Long dtoBId(Dto dto) {
        if ( dto == null ) {
            return null;
        }
        DtoB b = dto.b;
        if ( b == null ) {
            return null;
        }
        Long id = b.id;
        if ( id == null ) {
            return null;
        }
        return id;
    }

    private Long dtoAId(Dto dto) {
        if ( dto == null ) {
            return null;
        }
        DtoA a = dto.a;
        if ( a == null ) {
            return null;
        }
        Long id = a.id;
        if ( id == null ) {
            return null;
        }
        return id;
    }
}