美文网首页
MapStruct实现对象映射

MapStruct实现对象映射

作者: EugeneHeen | 来源:发表于2021-12-14 14:07 被阅读0次

1 序

mapstruct.png

MapStruct是一个属性映射工具,只需要使用@Mapper注解标注的映射接口。MapStruct就会自动生成实现这个映射接口的实现类,避免了复杂繁琐的映射实现。MapStruct官网地址: http://mapstruct.org/

2 准备工作

2.1 定义映射示例Bean

  • 定义Mode Bean
package com.eugeneheen.mapstruct.api.model;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.time.LocalDateTime;

@Data
public class UserModel {
    private Long id;

    private String name;

    private String phone;

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    LocalDateTime createTm;

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    LocalDateTime updateTm;
}
  • 定义Do Bean
package com.eugeneheen.mapstruct.dao.dataobject;

import lombok.Data;
import javax.persistence.*;
import java.time.LocalDateTime;

@Data
@Entity(name = "t_user")
public class UserDo {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column
    private String name;

    @Column
    private String phone;

    @Column(name = "create_tm")
    LocalDateTime createTm;

    @Column(name = "update_tm")
    LocalDateTime updateTm;
}

2.2 示例使用的相关依赖

  • Lombok
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.22</version>
    <optional>true</optional>
</dependency>
  • MapStruct官方依赖
<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct</artifactId>
    <version>1.4.2.Final</version>
</dependency>
<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-processor</artifactId>
    <version>1.4.2.Final</version>
</dependency>
<dependency>
    <groupId>org.mapstruct.extensions.spring</groupId>
    <artifactId>mapstruct-spring-annotations</artifactId>
    <version>0.1.0</version>
</dependency>
  • MapStruct第三方依赖
<dependency>
     <groupId>io.github.zhaord</groupId>
     <artifactId>mapstruct-spring-plus-boot-starter</artifactId>
     <version>1.0.1.RELEASE</version>
</dependency>

3 示例

3.1 关于依赖

3.1.1 Maven

  • SpringBoot单模块项目:直接在POM文件加入相关依赖即可。
  • SpringBoot多模块项目
    • 打包的模块,POM文件加入以下依赖:
    <build>
      <plugins>
          <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-compiler-plugin</artifactId>
              <version>3.8.1</version>
              <configuration>
                  <source>1.8</source>
                  <target>1.8</target>
                  <encoding>UTF-8</encoding>
              </configuration>
          </plugin>
          <plugin>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-maven-plugin</artifactId>
              <version>2.4.1</version>
              <configuration>
                  <mainClass>com.eugeneheen.mapstruct.MapStructApplication</mainClass>
                  <skip>false</skip>
                  <layers>
                  <enabled>true</enabled>
                  </layers>
                  <excludes>
                  <!-- 打包的时候忽略lombok,解决生成了maptruct的实现类,但该类只创建了对象,没有进行赋值 -->
                  <exclude>
                      <groupId>org.projectlombok</groupId>
                      <artifactId>lombok</artifactId>
                  </exclude>
                  </excludes>
              </configuration>
              <executions>
                  <execution>
                  <id>repackage</id>
                  <goals>
                      <goal>repackage</goal>
                  </goals>
                  </execution>
              </executions>
          </plugin>
      </plugins>
    </build>
    
    • 定义映射接口的模块,POM文件加入以下依赖:
      <dependencies>
          <dependency>
              <groupId>org.mapstruct</groupId>
              <artifactId>mapstruct</artifactId>
              <version>1.4.2.Final</version>
          </dependency>
          <dependency>
              <groupId>org.mapstruct</groupId>
              <artifactId>mapstruct-processor</artifactId>
              <version>1.4.2.Final</version>
          </dependency>
          <dependency>
              <groupId>org.projectlombok</groupId>
              <artifactId>lombok</artifactId>
              <version>1.18.22</version>
              <optional>true</optional>
          </dependency>
      </dependencies>
      <build>
          <plugins>
              <plugin>
                  <groupId>org.apache.maven.plugins</groupId>
                  <artifactId>maven-compiler-plugin</artifactId>
                  <version>3.8.1</version>
                  <configuration>
                      <source>1.8</source>
                      <target>1.8</target>
                      <encoding>UTF-8</encoding>
                      <annotationProcessorPaths>
                          <!-- 此处,lombok依赖一定要放在,Mapstruct-processor依赖之前。否则,生成了maptruct的实现类,但该类只创建了对象,没有进行赋值 -->
                          <path>
                              <groupId>org.projectlombok</groupId>
                              <artifactId>lombok</artifactId>
                              <version>1.18.22</version>
                          </path>
                          <path>
                              <groupId>org.mapstruct</groupId>
                              <artifactId>mapstruct-processor</artifactId>
                              <version>1.4.2.Final</version>
                          </path>
                      </annotationProcessorPaths>
                  </configuration>
              </plugin>
          </plugins>
      </build>
      

3.1.2 Gradle

  • version >= 4.6
dependencies {
    implementation 'org.mapstruct:mapstruct:1.4.2.Final'
    annotationProcessor 'org.mapstruct:mapstruct-processor:1.4.2.Final'
}
  • version < 4.6
plugins {
    id 'net.ltgt.apt' version '0.21'
}
dependencies {
    compile 'org.mapstruct:mapstruct:1.4.2.Final'
    apt 'org.mapstruct:mapstruct-processor:1.4.2.Final'
}

3.2 基础使用示例

  • 定义映射接口
package com.eugeneheen.mapstruct.api.struct;

import com.yongyou.eshs.api.model.UserModel;
import com.yongyou.eshs.dao.dataobject.UserDo;
import org.mapstruct.Mapper;

@Mapper
public interface IUserStruct {
    IUserStruct INSTANCE = Mappers.getMapper( IUserStruct.class );
    
    UserDo modelToDo(UserModel userModel);
    UserModel doToModel(UserDo user);
}
  • Service中使用
public interface IUserService {
    UserModel findById(Long id);
}

@Service
public class UserServiceImpl implements IUserService {

    @Autowired
    private IUserRepository userRepository;

    @Override
    public UserModel findById(Long id) {
        UserDo user = this.userRepository.getOne(id);
        // 此处,由于映射定义未使用Spring注入,所以使用常量获实例再调用映射方法
        return IUserStruct.INSTANCE.toModel(user);
    }
}

3.3 注入到Spring的使用示例

  • 定义映射接口
  package com.eugeneheen.mapstruct.api.struct;
  
  import com.yongyou.eshs.api.model.UserModel;
  import com.yongyou.eshs.dao.dataobject.UserDo;
  import org.mapstruct.Mapper;
  
   // 使用@Mapper注解的componentModel属性值制定为Spring,实现Spring注入
  @Mapper(componentModel = "spring")
  public interface IUserStruct {
      UserDo modelToDo(UserModel userModel);
      UserModel doToModel(UserDo user);
  }
  • Service中使用
public interface IUserService {
    UserModel findById(Long id);
}

@Service
public class UserServiceImpl implements IUserService {

    @Autowired
    private IUserRepository userRepository;

    // 此处,注入由Spring管理的映射实现
    @Autowired
    private IUserStruct userStruct;

    @Override
    public UserModel findById(Long id) {
        UserDo user = this.userRepository.getOne(id);
        return this.userStruct.toModel(user);
    }
}

3.4 使用Spring扩展依赖的使用示例

待续......

4 常见问题

4.1 Maven构建出现生成了MapStruct的实现类,但该类只创建了对象,没有进行赋值的问题

  • 定义映射接口的模块/工程,maven-compiler-plugin插件,配置lombok-mapstruct-binding依赖,且依赖版本由0.1.0升级到0.2.0
<dependencies>
    <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct</artifactId>
        <version>1.4.2.Final</version>
    </dependency>
    <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct-processor</artifactId>
        <version>1.4.2.Final</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.22</version>
        <optional>true</optional>
    </dependency>
</dependencies>
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
                <encoding>UTF-8</encoding>
                <annotationProcessorPaths>
                    <!-- 此处,lombok依赖一定要放在,Mapstruct-processor依赖之前。否则,生成了maptruct的实现类,但该类只创建了对象,没有进行赋值 -->
                    <path>
                        <groupId>org.projectlombok</groupId>
                        <artifactId>lombok</artifactId>
                        <version>1.18.22</version>
                    </path>
                    <path>
                        <groupId>org.projectlombok</groupId>
                        <artifactId>lombok-mapstruct-binding</artifactId>
                        <!-- 如果是0.1.0 有可能出现生成了MapStruct的实现类,但该类只创建了对象,没有进行赋值 -->
                        <version>0.2.0</version>
                    </path>
                    <path>
                        <groupId>org.mapstruct</groupId>
                        <artifactId>mapstruct-processor</artifactId>
                        <version>1.4.2.Final</version>
                    </path>
                </annotationProcessorPaths>
            </configuration>
        </plugin>
    </plugins>
</build>
  • 多项目打包时,在父项目/打包模块POM中配置spring-boot-maven-plugin插件时,排除``依赖。详细配置见3.1.1章节,SpringBoot多模块项目配置

5 MapStruct与各种BeanUtil性能比较

工具 十个对象复制1次 一万个对象复制1次 一百万个对象复制1次 一百万个对象复制5次
MapStruct 0ms 3ms 96ms 281ms
Hutool的BeanUtil 23ms 102ms 1734ms 8316ms
Spring的BeanUtils 2ms 47ms 726ms 3676ms
Apache的BeanUtils 20ms 156ms 10658ms 52355ms

测试数据仅供参考,根据不同主机配置均有不同,单此处数据也能客观表现性能

相关文章

  • MapStruct实现对象映射

    1 序 MapStruct是一个属性映射工具,只需要使用@Mapper注解标注的映射接口。MapStruct就会自...

  • jdk11使用MapStruct

    背景介绍 对比几个对象映射框架,MapStruct性能较好,且实现相对容易,网上和官方文档中只支持到jdk1.8,...

  • java对象映射工具--mapStruct

    一般工程中会同时出现DTO和Entity两种类型的对象,Entity是数据库表直接对应的实体类,和数据库交互;DT...

  • MapStruct

    概述 MapStruct 可以将某几种类型的对象映射为另外一种类型,如将多个 DO(业务实体对象) 对象转换为 D...

  • 简化mapstruct代码: mapstruct-spring-

    mapstruct MapStruct 是一个属性映射工具,只需要定义一个 Mapper 接口,MapStruc...

  • 使用mapstruct复制对象

    MapStruct 注解的关键词 基本用法 两对象属性不必完全一直,指挥按字段匹配 字段映射 userName 为...

  • mapstruct 和lombok 结合之后mapstruct生

    lombok和mapstruct配合转换bean后,mapstruct生成空的实现. 如果出现mapstruct和...

  • 映射框架MapStruct

    一、MapStruct 开发中,我们经常需要将PO转DTO、DTO转PO等一些实体间的转换。比较出名的有BeanU...

  • MapStruct:实体映射

    一、MapStruct作用是什么? 现在有这么个场景,从数据库查询出来了一个user对象(包含id,用户名,密码,...

  • ORM简介

    Object/Relational Mapping:对象-关系映射。实现对象和关系型数据的映射。对象和关系型数据是...

网友评论

      本文标题:MapStruct实现对象映射

      本文链接:https://www.haomeiwen.com/subject/wauefrtx.html