带有@aftermapping的MapStruct批量转换

带有@aftermapping的MapStruct批量转换,mapstruct,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 C

我想在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())));
}
公共抽象CatUI转换(Cat);
公共摘要列表转换(列表猫);
@后映射
public void populateCatName(Cat Cat,@MappingTarget CatUI CatUI){
字符串名称=_someRemoteService.getCatName(catUI.getId());
catUI.setName(名称);
}
@后映射
public void populateCatNames(列表猫,@MappingTarget列表猫){
Map idToNameMap=\u someRemoteService.getCatNames(catUIs.stream().Map((c)->c.getId()).collect(Collectors.toList());
catUIs.forEach((c)->c.setName(idToNameMap(c.getId()));
}
我不希望在处理列表转换时调用populateCatName,从而复制我的装饰


无论如何要做到这一点?

对于1.1.0.Final,您必须定义两个入口点(映射器),一个在列表上有转换,另一个没有转换

我建议您试用新的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
    }
}
公共接口CatMappingContext{
@后映射
公共默认void populateCatName(Cat Cat,@MappingTarget CatUI CatUI){
//默认值为零
}
@后映射
public void populateCatNames(列表猫,@MappingTarget列表猫){
//默认值为零
}
}
和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())));
    }
}
公共类SingleMappingContext实现CatMappingContext{
@后映射
public void populateCatName(Cat Cat,@MappingTarget CatUI CatUI){
字符串名称=_someRemoteService.getCatName(catUI.getId());
catUI.setName(名称);
}
}
公共类ListMappingContext实现了CatMappingContext{
@后映射
public void populateCatNames(列表猫,@MappingTarget列表猫){
Map idToNameMap=\u 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);
}
公共接口CatMapper{
公共CatUI转换(Cat Cat、@Context CatMappingContext Context);
公共列表转换(列表猫,@Context-CatMappingContext-Context);
}
然后,您需要使用上下文
SingleMappingContext
ListMappingContext
的正确实例调用方法