MapStruct 对象转换使用方式

简介

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>

使用示例

这里通过创建 UserUserDTO 两个类进行进行相互转换

创建 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);
    }
}
相关推荐
希忘auto1 分钟前
详解MySQL安装
java·mysql
冰淇淋烤布蕾12 分钟前
EasyExcel使用
java·开发语言·excel
拾荒的小海螺19 分钟前
JAVA:探索 EasyExcel 的技术指南
java·开发语言
Jakarta EE35 分钟前
正确使用primefaces的process和update
java·primefaces·jakarta ee
马剑威(威哥爱编程)43 分钟前
哇喔!20种单例模式的实现与变异总结
java·开发语言·单例模式
java—大象1 小时前
基于java+springboot+layui的流浪动物交流信息平台设计实现
java·开发语言·spring boot·layui·课程设计
杨哥带你写代码2 小时前
网上商城系统:Spring Boot框架的实现
java·spring boot·后端
camellias_2 小时前
SpringBoot(二十一)SpringBoot自定义CURL请求类
java·spring boot·后端
布川ku子2 小时前
[2024最新] java八股文实用版(附带原理)---Mysql篇
java·mysql·面试
向阳12182 小时前
JVM 进阶:深入理解与高级调优
java·jvm