12基于qualifiers选择Mapping方法

如果MapStruct在将A类型转换为B类型时,匹配到多个映射方法【这些映射方法的入参都是A类型,返回值是B类型】。则程序会报编译错误,MapStruct会给出相应的提示。

我们先来看个具体的例子。

实体类型定义如下:

@Data
public class OriginalRelease {

    private String title;

}
@Data
public class GermanRelease {

    private String title;

}

我们有个工具类支持将title转换成德语和英语。

public class Titles {

    /**
     * 将title 转换为 德语
     *
     * @param title
     * @return
     */
    public String transTitle2German(String title) {
        return "German: " + title;
    }

    /**
     * 将title 转换为 英语
     *
     * @param title
     * @return
     */
    public String transTitle2English(String title) {
        return "English: " + title;
    }
}

Mapper类定义如下:

@Mapper(uses = Titles.class)
public interface ReleaseMapper {

    GermanRelease toGerman(OriginalRelease release);

}

上述代码编译后,会报如下错误:

Ambiguous mapping methods found for mapping property "String title" to String: String Titles.transTitle2German(String title), String Titles.transTitle2English(String title). See https://mapstruct.org/faq/#ambiguous for more info.

大概意思就是:MapStruct在将OriginalRelease.title转换为GermanRelease.title时。匹配到2个方法,分别是:String Titles.transTitle2German(String title) 和 String Titles.transTitle2English(String title)。

MapStruct无法决定使用哪个方法进行转换,因此报错。

针对上面的场景,MapStruct提供了qualifiers机制,供程序员明确指定使用哪个方法进行转换。

qualifiers机制提供了两种方式:qualifiedBy 和 qualifiedByName。下面我们分别来介绍这两种用法。


1、qualifiedBy

(1)首先我们需要定义注解,该注解用于标识我们的转换方法(Mapping Method);

@Qualifier
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.CLASS)
public @interface ToGerman {
}

@Qualifier
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.CLASS)
public @interface ToEnglish {
}

关于定义的注解,这里说三点:

(1)该注解必须使用@Qualifier标注;

(2)该注解只能作用于方法;

(3)该注解RetentionPolicy为RetentionPolicy.CLASS

(2)使用定义的注解标注转换方法(Mapping Method);

如此一来,注解和转换方法就建立了对应关系。

public class Titles {
    
    @ToGerman
    public String transTitle2German(String title) {
        return "German: " + title;
    }
    
    @ToEnglish
    public String transTitle2English(String title) {
        return "English: " + title;
    }
    
}

(3)在Mapper中使用注解,指定转换方法。

为@Mapping#qualifiedBy指定对应的注解,用于表示使用其标注的转换方法进行转换。

@Mapper(uses = Titles.class)
public interface ReleaseMapper {

    ReleaseMapper INSTANCE = Mappers.getMapper(ReleaseMapper.class);

    @Mapping(target = "title", qualifiedBy = ToGerman.class)
    GermanRelease toGerman(OriginalRelease release);

    @Mapping(target = "title", qualifiedBy = ToEnglish.class)
    EnglishRelease toEnglish(OriginalRelease release);

}

注意:这里的uses = Titles.class是必须加上的,否则MapStruct会报找不到对应注解标注的转换方法。

(4)生成的Mapper实现类的代码

public class ReleaseMapperImpl implements ReleaseMapper {

    private final Titles titles = new Titles();

    @Override
    public GermanRelease toGerman(OriginalRelease release) {
        if ( release == null ) {
            return null;
        }

        GermanRelease germanRelease = new GermanRelease();

        germanRelease.setTitle( titles.transTitle2German( release.getTitle() ) );

        return germanRelease;
    }

    @Override
    public EnglishRelease toEnglish(OriginalRelease release) {
        if ( release == null ) {
            return null;
        }

        EnglishRelease englishRelease = new EnglishRelease();

        englishRelease.setTitle( titles.transTitle2English( release.getTitle() ) );

        return englishRelease;
    }
}


2、qualifiedByName

(1)使用@Named注解为转换方法设置别名。

public class Titles {

    @Named("toGerman")
    public String transTitle2German(String title) {
        return "German: " + title;
    }

    @Named("toEnglish")
    public String transTitle2English(String title) {
        return "English: " + title;
    }

}

(2)在Mapper中使用别名,指定转换方法。

为@Mapping#qualifiedBy指定对应的别名,用于表示使用其标注的转换方法进行转换。

@Mapper(uses = Titles.class)
public interface ReleaseMapper {

    ReleaseMapper INSTANCE = Mappers.getMapper(ReleaseMapper.class);

    @Mapping(target = "title", qualifiedByName = "toGerman")
    GermanRelease toGerman(OriginalRelease release);

    @Mapping(target = "title", qualifiedByName = "toEnglish")
    EnglishRelease toEnglish(OriginalRelease release);

}

注意:这里的uses = Titles.class是必须加上的,否则MapStruct会报找不到对应别名标注的转换方法。

展开阅读全文

页面更新:2024-04-25

标签:会报   德语   方法   注解   英语   别名   定义   机制   错误   类型

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号

Top