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);
    }
}
相关推荐
爪哇学长6 分钟前
Spring框架深度剖析:特性、安全与优化
java·安全·spring
乄bluefox7 分钟前
SpringBoot中使用Sharding-JDBC实战(实战+版本兼容+Bug解决)
java·数据库·spring boot·redis·后端·缓存·bug
TimberWill13 分钟前
字符串-07-判断两个IP是否属于同一子网
java·网络协议·tcp/ip
往日情怀酿做酒 V176392963823 分钟前
Django基础配置
后端·python·django
2401_8576009536 分钟前
企业OA管理系统:Spring Boot技术实践与案例分析
java·spring boot·后端
running up that hill40 分钟前
数据库中的增删改查操作、聚合函数、内置函数、分组查询
java·数据库·sql·mysql
潜洋44 分钟前
Spring Boot 教程之六:Spring Boot - 架构
java·spring boot·后端·架构
希忘auto1 小时前
详解RabbitMQ在Ubuntu上的安装
java·rabbitmq
铅华尽1 小时前
Java---JDBC案例--手机信息管理系统
java·开发语言·智能手机
小码的头发丝、1 小时前
Maven的安装与配置
java·数据库·maven