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

nbc*_*chn 10 java mapstruct

这是我的上下文:我使用byteBuddy动态生成一个类,该类根据外部配置将对象转换为另一个对象.我遇到了一些问题,我想找到另一种方法,就是我发现MapStruct的方法.

所以我尝试构建简单的映射器,我想知道是否有可能自定义注释以添加转换函数.比如我想:

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

在mapper实现上我会有类似的东西:

 public TypeDest toSiteCatTag(TypeSrc obj) {

    if ( obj == null ) {

        return null;
    }

    TypeDest objDest = new TypeDest();

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

    return objDest;
}
Run Code Online (Sandbox Code Playgroud)

如果有人能帮助我实现这一目标,我将不胜感激,这将为我节省大量时间.

提前致谢.

Fil*_*lip 21

如果你的2种类型TypeDest,并TypeSrc在运行时也不会产生,也就是说,它们是你的编译的类,那么你可以达到你想要的.MapStruct在运行时不起作用,因为它是一个Annotation Processor并生成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));
    }
}
Run Code Online (Sandbox Code Playgroud)

有一种方法可以在映射器中没有自定义方法的情况下执行此操作,但是您需要在某处应用toInteger然后toSquare转换的方法.如果你有签名的方法Integer squaredString(String obj)在你的Formatter.

例如

@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
}
Run Code Online (Sandbox Code Playgroud)

然后你可以在mapper中执行此操作:

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

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

上面的例子中,因为将仅被施加到特定的映射qualifedByName/ qualified被使用.如果你想有一个转换以不同的方式StringInteger,那么你就可以在你的映射或者在某些类别的定义方法Mapper#uses与签名Integer convertString(String obj).然后MapStruct将从委托转换StringInteger该方法.

你可以找到更多关于预选赛映射这里的参考文档中,并在这里,了解有关映射方法解决的更多信息.