使用 Mapstruct 映射集合并为单个实例指定方法?

Map a collection using Mapstruct and specify method for a single instance?

我有一个 mapstruct class 具有以下功能

    abstract CustomApplication convertCustomApplication(ApplicationDTO source);

    abstract RegularApplication convertRegularApplication(ApplicationDTO source);

    @Named("mainConverter")
    public App mainConverter(ApplicationDTO source) {
        return source.isCustom() ? convertCustomApplication(source) : convertRegularApplication(source);
    }

    //@Mapping( qualifiedByName = "mainConverter")
    abstract public List<App> convertApplications(List<ApplicationDTO> applicationList);

CustomApplication和RegularApplication都是扩展App,所以我有mainConverter根据isCustom字段调用转换器。

问题是,当我尝试构建它时,我得到了一个不明确的映射错误,因为 mainConverter、convertRegularApplication 和 convertCustomApplication 都从 ApplicationDTO 映射到 App(或 App 的 subclass)。所以convertApplications不知道用什么。 有什么办法可以明确告诉它调用 mainConverter?我想要像 @Mapping( qualifiedByName = "mainConverter") 这样的东西,我把它放在 convertApplications 上面,(但它当然不起作用) 有谁知道我该怎么做?谢谢!

为了实现您的目标,您需要使用 IterableMapping#qualifiedByName

此 属性 旨在增强列表的选择。

例如

    abstract CustomApplication convertCustomApplication(ApplicationDTO source);

    abstract RegularApplication convertRegularApplication(ApplicationDTO source);

    @Named("mainConverter")
    public App mainConverter(ApplicationDTO source) {
        return source.isCustom() ? convertCustomApplication(source) : convertRegularApplication(source);
    }

    @IterableMapping(qualifiedByName = "mainConverter")
    abstract public List<App> convertApplications(List<ApplicationDTO> applicationList);

备选方案

您正在制作 mainConverter 合格的方法。但是,看起来该方法已经重定向到更具体的方法。因此,我建议对其他两种方法进行限定,并从 mainConverter 中删除限定。然后你不需要为可迭代映射做任何事情。

例如

    @Named("customApplication")
    abstract CustomApplication convertCustomApplication(ApplicationDTO source);

    @Named("regularApplication")
    abstract RegularApplication convertRegularApplication(ApplicationDTO source);

    public App mainConverter(ApplicationDTO source) {
        return source.isCustom() ? convertCustomApplication(source) : convertRegularApplication(source);
    }

    abstract public List<App> convertApplications(List<ApplicationDTO> applicationList);