简介
MapStruct
是一种实体映射框架,用于生成类型安全的 Bean 映射类的 Java 注解处理器。只需定义一个 mapper
接口,在该接口中声明需要映射的方法。在编译过程中,MapStruct 就会生成该接口的实现。
注意:MapStruct 不是通过反射实现,而是通过使用纯 Java 的方法调用源对象和目标对象之间进行映射,因此效率很高。
与动态映射框架相比,MapStruct 具有以下优点:
- 使用纯 Java 方法代替 Java 反射机制快速执行。
- 编译时类型安全:只能映射彼此的对象和属性,不能映射一个 Order 实体到一个自定义 DTO 中等等。
- 如果无法映射实体或属性,则在编译时清楚错误报告。
相关依赖
xml
<properties>
<lombok.version>1.18.30</lombok.version>
<mapstruct.version>1.5.5.Final</mapstruct.version>
</properties>
<dependencies>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
使用示例
这里通过创建 User
和 UserDTO
两个类进行进行相互转换
创建 User
类,代码如下:
java
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
/**
* 用户编号
*/
private Integer id;
/**
* 用户名
*/
private String name;
/**
* 年龄
*/
private Integer age;
}
创建 UserDTO
类,代码如下:
java
@Data
public class UserDTO {
/**
* 用户编号
*/
private Integer userId;
/**
* 用户名
*/
private String name;
/**
* 年龄
*/
private Integer age;
}
1、示例一
创建 UserConvert
接口,作为 User 相关的转换器,代码如下:
java
@Mapper
public interface UserConvert {
UserConvert INSTANCE = Mappers.getMapper(UserConvert.class);
/**
* 将 User 对象转换为 UserDTO 对象
*
* @param user User 对象
* @return UserDTO 对象
*/
UserDTO toUserDTO(User user);
}
相关说明:
1、
@Mapper
注解:用于声明该接口是一个 Map Struct Mapper 映射器。2、
UserConvert INSTANCE = Mappers.getMapper(UserConvert.class);
通过调用Mappers.getMapper(Class<T> clazz)
方法,获取 MapStruct 帮助我们自动生成 UserConvert 实现类的对象。
测试代码如下:
java
public class IssuesTest {
@Test
public void test01() {
User user = new User(1001, "张三", 18);
UserDTO userDTO = UserConvert.INSTANCE.toUserDTO(user);
System.out.println("userDTO = " + userDTO);
}
}
2、示例二
不同对象转换时,可能会存在属性不是完全映射的情况,例如:属性名不同等情况,可以通过使用 @Mapping
注解,配置对应的映射关系,如上述 User 类的 id
属性 和 UserDTO 类的 userId
属性,这两个属性名不能,从而无法将 User 类的 id
属性映射到 UserDTO 类的 userId
属性中。
此时修改 UserConvert
接口,代码如下:
java
@Mapper
public interface UserConvert {
UserConvert INSTANCE = Mappers.getMapper(UserConvert.class);
/**
* 将 User 对象转换为 UserDTO 对象
*
* @param user User 对象
* @return UserDTO 对象
*/
@Mappings(value = {
@Mapping(source = "id", target = "userId")
})
UserDTO toUserDTO02(User user);
}
相关说明:
1、
@Mapping
注解的source
属性需要设置源目标的属性,这里是将 User 转换为 UserDTO,所以设置为User 对象的id
属性名。2、
@Mapping
注解的target
属性需要设置目标对象的属性,这里是将 User 转换为 UserDTO,所以设置为 UserDTO 对象的userId
属性名。
测试代码如下:
java
public class IssuesTest {
@Test
public void test02() {
User user = new User(1001, "张三", 18);
UserDTO userDTO = UserConvert.INSTANCE.toUserDTO02(user);
System.out.println("userDTO = " + userDTO);
}
}
3、示例三
MapStruct 还支持将多个对象转换为一个对象,例如:需要将 User、Address对象转换为 UserDTO 对象。
创建 Address
对象,代码如下:
java
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Address {
/**
* 地址
*/
private String addressName;
}
修改 UserDTO
对象,代码如下:
java
@Data
public class UserDTO {
/**
* 用户编号
*/
private Integer userId;
/**
* 用户名
*/
private String name;
/**
* 年龄
*/
private Integer age;
/**
* 地址
*/
private String address;
}
修改 UserConvert
接口,代码如下:
java
@Mapper
public interface UserConvert {
UserConvert INSTANCE = Mappers.getMapper(UserConvert.class);
/**
* 将 User 对象转换为 UserDTO 对象
*
* @param user User 对象
* @param address Address 对象
* @return UserDTO 对象
*/
@Mappings(value = {
@Mapping(source = "user.id", target = "userId"),
@Mapping(source = "address.addressName", target = "address")
})
UserDTO toUserDTO03(User user, Address address);
}
测试代码:
java
public class IssuesTest {
@Test
public void test03() {
User user = new User(1001, "张三", 18);
Address address = new Address("广东省");
UserDTO userDTO = UserConvert.INSTANCE.toUserDTO03(user, address);
System.out.println("userDTO = " + userDTO);
}
}