MapStruct :丰富映射注释以定义自定义映射器

MapStruct : enrich mapping annotation to define custom mapper

这是我的上下文:我正在使用 byteBuddy 动态生成一个 class,它根据外部配置将一个对象转换为另一个对象。我遇到了一些问题,我想找到一个替代方案,这就是我发现 MapStruct 的方式。

所以我尝试构建简单的映射器,我想知道是否可以自定义注释以添加转换功能。例如我想要:

@Mapping(
    source = "mySourceField", 
    sourceType = "String",
    target = "myTargetField",
    targetType = "Integer",
    transformation = {"toInteger", "toSquare"}
),

在映射器实现上,我会有类似的东西:

 public TypeDest toSiteCatTag(TypeSrc obj) {

    if ( obj == null ) {

        return null;
    }

    TypeDest objDest = new TypeDest();

    objDest.myTargetField = Formatter.toSquare(
        Formatter.toInteger(obj.mySourceField));

    return objDest;
}

如果有人能帮助我实现这一点,我将不胜感激,这会节省我很多时间。

提前致谢。

如果你的 TypeDestTypeSrc 两种类型不是在运行时生成的,即它们是你编译的 类,那么你可以实现你想要的。 MapStruct 在运行时不起作用,因为它是一个注释处理器并生成 java 代码。如果有一些问题,比如你试图映射不存在的字段或者映射方法不明确,那么你将得到编译时错误。

它看起来像:

@Mapper
public interface MyMapper {

    @Mapping(source = "mySourceField", target = "myTargetField", qualifiedByName = "myTransformation")// or you can use a custom @Qualifier annotation with qualifiedBy
    TypeDest toSiteCatTag(TypeSrc obj);

    @Named("myTransformation")// or your custom @Qualifier annotation
    default Integer myCustomTransformation(String obj) {
        return Formatter.toSquare(Formatter.toInteger(obj));
    }
}

有一种方法可以在映射器中没有自定义方法的情况下执行此操作,但您需要在某个地方有一个应用 toInteger 然后 toSquare 转换的方法。如果您的 Formatter.

中有一个带有签名 Integer squaredString(String obj) 的方法

例如

@Qualifier
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.CLASS)
public @interface SquaredString {}

public class Formatter {

    @SquaredString// you can also use @Named, this is just as an example
    public static Integer squaredString(String obj) {
        return toSquare(toInteger(obj));
    }
    //your other methods are here as well
}

然后您可以在映射器中执行此操作:

@Mapper(uses = { Formatter.class })
public interface MyMapper {

    @Mapping(source = "mySourceField", target = "myTargetField", qualifiedBy = SquaredString.class)
    TypeDest toSiteCatTag(TypeSrc obj);
}

由于使用了qualifedByName / qualified,因此上述示例仅适用于特定映射。如果你想用不同的方式将 String 转换为 Integer,那么你可以在你的 Mapper 或 Mapper#uses 中的某些 类 中定义一个方法签名 Integer convertString(String obj)。然后 MapStruct 会将 StringInteger 的转换委托给此方法。

您可以找到有关使用限定符进行映射的更多信息here in the reference documentation, and here,以了解有关映射方法解析的更多信息。