java MapStruct :丰富映射注释以定义自定义映射器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/44334067/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
MapStruct : enrich mapping annotation to define custom mapper
提问by nbchn
Here is my context: I am using byteBuddy to dynamically generate a class that transform an object into another one based on a external configuration. I encountered some issues and I wanted to find an alternative that's how I discovered MapStruct.
这是我的上下文:我使用 byteBuddy 动态生成一个类,该类根据外部配置将对象转换为另一个对象。我遇到了一些问题,我想找到一个替代方案,这就是我发现 MapStruct 的方式。
So I tried to build simple mapper and I wanted to know if there is the possibility to customize the annotation to add transformation functions. For instance I would like to have:
所以我尝试构建简单的映射器,我想知道是否有可能自定义注释以添加转换功能。例如,我想要:
@Mapping(
source = "mySourceField",
sourceType = "String",
target = "myTargetField",
targetType = "Integer",
transformation = {"toInteger", "toSquare"}
),
And on the mapper implementation I would have something like :
在映射器实现上,我会有类似的东西:
public TypeDest toSiteCatTag(TypeSrc obj) {
if ( obj == null ) {
return null;
}
TypeDest objDest = new TypeDest();
objDest.myTargetField = Formatter.toSquare(
Formatter.toInteger(obj.mySourceField));
return objDest;
}
If someone can help me to achieve that I would be grateful and it would save me a lot of time.
如果有人能帮助我实现这一目标,我将不胜感激,这将为我节省很多时间。
Thanks in advance.
提前致谢。
回答by Filip
If your 2 types TypeDest
and TypeSrc
are not generated on runtime, i.e. they are your compiled classes, then you can achieve what you want. MapStruct does not work on runtime as it is an Annotation Processor and generates java code. If there are some issues, like you are trying to map non-existing fields or there are ambiguous mapping methods then you will get compile time errors.
如果你的2种类型TypeDest
,并TypeSrc
在运行时也不会产生,也就是说,它们是你的编译的类,那么你可以达到你想要的。MapStruct 在运行时不起作用,因为它是一个注释处理器并生成 java 代码。如果存在一些问题,例如您试图映射不存在的字段或存在不明确的映射方法,那么您将收到编译时错误。
It will look something like:
它看起来像:
@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));
}
}
There is a way to do it without the custom method in the mapper, but you'll need to have a method somewhere that applies the toInteger
and then toSquare
transformation. If you have a method with the signature Integer squaredString(String obj)
in your Formatter
.
有一种方法可以在映射器中不使用自定义方法的情况下执行此操作,但是您需要在某处使用一个方法来应用toInteger
然后toSquare
转换。如果您Integer squaredString(String obj)
的Formatter
.
e.g.
例如
@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
}
Then you can do this in your mapper:
然后你可以在你的映射器中做到这一点:
@Mapper(uses = { Formatter.class })
public interface MyMapper {
@Mapping(source = "mySourceField", target = "myTargetField", qualifiedBy = SquaredString.class)
TypeDest toSiteCatTag(TypeSrc obj);
}
The examples above will only be applied to the specific mapping since qualifedByName
/ qualified
is used. If you want to have a different way of converting a String
to Integer
, then you can define a method either in your Mapper or in some of the classes in Mapper#uses
with the signature Integer convertString(String obj)
. MapStruct will then delegate the conversion from String
to Integer
to this method.
由于使用了qualifedByName
/ ,qualified
因此上面的示例仅适用于特定映射。如果您想以不同的方式将 a 转换String
为Integer
,那么您可以在 Mapper 或Mapper#uses
带有签名的某些类中定义一个方法Integer convertString(String obj)
。然后MapStruct将从委托转换String
到Integer
该方法。
You can find more about mapping with qualifiers herein the reference documentation, and herefor more information regarding the mapping method resolution.