使用@aftermapping进行MapStruct批量转换

时间:2017-05-26 02:10:19

标签: mapstruct

我想在DTO的单项转换后使用专用的@AfterMapping应用装饰,而在处理其集合转换风格时使用另一个专用的@AfterMapping,但不是两者。

public abstract CatUI convert(Cat cat);
public abstract List<CatUI> convert(List<Cat> cats);


@AfterMapping
public void populateCatName(Cat cat, @MappingTarget CatUI catUI) {
     String name = _someRemoteService.getCatName(catUI.getId());
     catUI.setName(name);
}

@AfterMapping
public void populateCatNames(List<Cat> cats, @MappingTarget List<CatUI> catUIs) {
     Map<Integer,String> idToNameMap = _someRemoteService.getCatNames(catUIs.stream().map((c) -> c.getId() ).collect(Collectors.toList());
     catUIs.forEach((c) -> c.setName(idToNameMap(c.getId())));
}

我不希望在处理List转换时调用populateCatName,因此重复我的装饰。

无论如何要做到这一点?

1 个答案:

答案 0 :(得分:1)

使用1.1.0.Final,你必须定义2个入口点(Mappers),其中一个带有转换列表,另一个没有它。

我建议你试试新的1.2.0.Beta2。有了这个,您可以使用新的@Context

您可以拥有如下界面:

public interface CatMappingContext {

    @AfterMapping
    public default void populateCatName(Cat cat, @MappingTarget CatUI catUI) {
        //nothing per default
    }

    @AfterMapping
    public void populateCatNames(List<Cat> cats, @MappingTarget List<CatUI> catUIs) {
        //nothing per default
    }
}

和2个实现:

public class SingleMappingContext implements CatMappingContext {

    @AfterMapping
    public void populateCatName(Cat cat, @MappingTarget CatUI catUI) {
        String name = _someRemoteService.getCatName(catUI.getId());
        catUI.setName(name);
    }
}

public class ListMappingContext implements CatMappingContext {

    @AfterMapping
    public void populateCatNames(List<Cat> cats, @MappingTarget List<CatUI> catUIs) {
        Map<Integer,String> idToNameMap = _someRemoteService.getCatNames(catUIs.stream().map((c) -> c.getId() ).collect(Collectors.toList());
        catUIs.forEach((c) -> c.setName(idToNameMap(c.getId())));
    }
}

最后你的映射器看起来像:

public interface CatMapper {

    public CatUI convert(Cat cat, @Context CatMappingContext context);
    public List<CatUI> convert(List<Cat> cats, @Context CatMappingContext context);
}

然后,您需要使用正确的上下文SingleMappingContextListMappingContext实例调用您的方法。