1. Overview
1.概述
In this article, we’ll learn how to use custom mapper with the MapStruct library.
在这篇文章中,我们将学习如何用MapStruct库使用自定义映射器。
The MapStruct library is used for mapping between Java bean types. By using a custom mapper with MapStruct, we can customize the default mapping methods.
MapStruct库用于Java bean类型之间的映射。通过使用MapStruct的自定义映射器,我们可以自定义默认的映射方法。
2. Maven Dependencies
2.Maven的依赖性
Let’s add the mapstruct library into our Maven pom.xml:
让我们把mapstruct库加入我们的Maven pom.xml。
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.3.1.Final</version>
</dependency>
To see the auto-generated methods inside the project’s target folder, we have to add the annotationProcessorPaths to the maven-compiler-plugin plugin:
要看到项目目标文件夹内自动生成的方法,我们必须在maven-compiler-plugin插件中加入annotationProcessorPaths。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.3.1.Final</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
3. Custom Mapper
3.自定义映射器
Custom mappers are used to solve specific conversion requirements. To achieve this, we have to define a method to do the conversion. Then, we must notify MapStruct about the method. Finally, MapStruct will call the method to do the conversion from source to target.
自定义映射器是用来解决特定的转换要求。为了实现这一点,我们必须定义一个方法来进行转换。然后,我们必须将该方法通知MapStruct。最后,MapStruct将调用该方法来完成从源码到目标码的转换。
For instance, let’s imagine that we have an app that calculates the user’s body mass index (BMI) report. To calculate BMI, we have to collect the user’s body values. To convert imperial units to metric units, we can use the custom mapper methods.
例如,让我们想象一下,我们有一个计算用户的身体质量指数(BMI)报告的应用程序。为了计算BMI,我们必须收集用户的身体数值。为了将英制单位转换成公制单位,我们可以使用自定义映射器方法。
There are two ways of using a custom mapper with MapStruct. We can either call the custom method by typing it inside the @Mapping annotation’s qualifiedByName property, or we can create an annotation for it.
在MapStruct中使用自定义映射器有两种方法。我们可以通过在@Mapping注解的qualifiedByName属性中输入自定义方法来调用它,或者我们可以为它创建一个注解。
Before we start, we have to define a DTO class to hold imperial values:
在我们开始之前,我们必须定义一个DTO类来保存帝国的价值。
public class UserBodyImperialValuesDTO {
private int inch;
private int pound;
// constructor, getters, and setters
}
Next, let’s define a DTO class to hold metric values:
接下来,让我们定义一个DTO类来保存度量值。
public class UserBodyValues {
private double kilogram;
private double centimeter;
// constructor, getters, and setters
}
3.1. Custom Mapper with Method
3.1.带有方法的自定义映射器
To start using custom mappers, let’s create an interface with the @Mapper annotation:
为了开始使用自定义映射器,让我们用@Mapper注解来创建一个接口。
@Mapper
public interface UserBodyValuesMapper {
//...
}
Second, let’s create our custom method with the return type we want and the argument we need to convert. We have to use the @Named annotation with the value parameter to inform MapStruct about the custom mapper method:
其次,让我们用我们想要的返回类型和需要转换的参数创建我们的自定义方法。我们必须使用@Named注解和值参数来通知MapStruct关于自定义映射器方法。
@Mapper
public interface UserBodyValuesMapper {
@Named("inchToCentimeter")
public static double inchToCentimeter(int inch) {
return inch * 2.54;
}
//...
}
And finally, let’s define the mapper interface method with the @Mapping annotation. Within this annotation, we’ll tell MapStruct about the source type, target type, and the method it will use:
最后,让我们用@Mapping注解来定义映射器的接口方法。在这个注解中,我们将告诉MapStruct关于源类型、目标类型以及它将使用的方法。
@Mapper
public interface UserBodyValuesMapper {
UserBodyValuesMapper INSTANCE = Mappers.getMapper(UserBodyValuesMapper.class);
@Mapping(source = "inch", target = "centimeter", qualifiedByName = "inchToCentimeter")
public UserBodyValues userBodyValuesMapper(UserBodyImperialValuesDTO dto);
@Named("inchToCentimeter")
public static double inchToCentimeter(int inch) {
return inch * 2.54;
}
}
Let’s test our custom mapper:
让我们测试一下我们的自定义映射器。
UserBodyImperialValuesDTO dto = new UserBodyImperialValuesDTO();
dto.setInch(10);
UserBodyValues obj = UserBodyValuesMapper.INSTANCE.userBodyValuesMapper(dto);
assertNotNull(obj);
assertEquals(25.4, obj.getCentimeter(), 0);
3.2. Custom Mapper with an Annotation
3.2.带有注解的自定义映射器
To use a custom mapper with an annotation, we have to define an annotation instead of the @Named annotation. Then, we have to inform MapStruct about the newly created annotation by specifying the @Mapping annotation’s qualifiedByName parameter.
要使用带有注解的自定义映射器,我们必须定义一个注解而不是@Named注解。然后,我们必须通过指定@Mapping注解的qualifiedByName参数来通知MapStruct关于新创建的注解。
Let’s see how we define the annotation:
让我们看看我们是如何定义注释的。
@Qualifier
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.CLASS)
public @interface PoundToKilogramMapper {
}
Let’s add the @PoundToKilogramMapper annotation to our poundToKilogram method:
让我们将@PoundToKilogramMapper注解添加到我们的poundToKilogram方法。
@PoundToKilogramMapper
public static double poundToKilogram(int pound) {
return pound * 0.4535;
}
Now, let’s define the mapper interface method with the @Mapping annotation. Within the mapping annotation, we’ll tell MapStruct about the source type, the target type, and the annotation class that it will use:
现在,让我们用@Mapping注解来定义映射器的接口方法。在映射注解中,我们将告诉MapStruct关于源类型、目标类型以及它将使用的注解类。
@Mapper
public interface UserBodyValuesMapper {
UserBodyValuesMapper INSTANCE = Mappers.getMapper(UserBodyValuesMapper.class);
@Mapping(source = "pound", target = "kilogram", qualifiedBy = PoundToKilogramMapper.class)
public UserBodyValues userBodyValuesMapper(UserBodyImperialValuesDTO dto);
@PoundToKilogramMapper
public static double poundToKilogram(int pound) {
return pound * 0.4535;
}
}
Finally, let’s test our custom mapper:
最后,让我们测试一下我们的自定义映射器。
UserBodyImperialValuesDTO dto = new UserBodyImperialValuesDTO();
dto.setPound(100);
UserBodyValues obj = UserBodyValuesMapper.INSTANCE.userBodyValuesMapper(dto);
assertNotNull(obj);
assertEquals(45.35, obj.getKilogram(), 0);
4. Conclusion
4.总结
In this article, we learned how to use a custom mapper with the MapStruct library.
在这篇文章中,我们学习了如何使用MapStruct库的自定义映射器。
The implementations of these examples and tests are available over on GitHub.
这些例子和测试的实现可以在GitHub上找到。