介绍

Mapstruct的性能远远高于BeanUtils,这应该是公司使用Mapstruct的主要原因

对象转换次数 属性个数 BeanUtils耗时 Mapstruct耗时
5千万次 6 14秒 1秒
5千万次 15 36秒 1秒
5千万次 25 55秒 1秒

Mapstruct 依赖

使用Mapstruct需要依赖的包如下,mapstruct、mapstruct-processor、lombok,可以去仓库中查看最新版本。

<dependency>
  <groupId>org.mapstruct</groupId>
  <artifactId>mapstruct</artifactId>
  <version>1.5.0.Final</version>
</dependency>
<dependency>
  <groupId>org.mapstruct</groupId>
  <artifactId>mapstruct-processor</artifactId>
  <version>1.5.0.Final</version>
</dependency>
<dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId> 
  <version>1.18.12</version>
</dependency>

<!-- 个人配置,配置Java17编译 -->
<properties>
  <maven.compiler.source>17</maven.compiler.source>
  <maven.compiler.target>17</maven.compiler.target>
</properties>

简单的属性拷贝

定义PO和BO

import lombok.Builder;
import lombok.Data;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;

import java.util.Date;

@Data
@Builder
class MyUserPo {
    private Long id;
    private Date createTime;
    private Long age;
    private String userNick;
    private String userVerified;
}

@Data
@Builder
class MyUserBO {
    private Long id;
    private Date createTime;
    private Long age;
    private String userNick;
    private String userVerified;
}

@Mapper
interface IPersonMapper {
    IPersonMapper INSTANCE = Mappers.getMapper(IPersonMapper.class);
    MyUserBO po1bo(MyUserPo userPo);
}

主函数进行拷贝

public class Main {
    public static void main(String[] args) {
        MyUserPo userPo = MyUserPo.builder()
            .id(0L)
            .userNick("mapstruct")
            .userVerified("ok")
            .age(17L)
            .build();
        System.out.println("PO: " + userPo);
        MyUserBO userEntity = IPersonMapper.INSTANCT.po1bo(userPo);
        System.out.println("BO: " + userEntity);
    }
}

Target 转换

@Mapping注解指定source和target字段名称对应关系,此处的意思就是在转化的过程中,将UserPo的userNick属性值赋值给UserBO的Nick属性。

import lombok.Builder;
import lombok.Data;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;

import java.util.Date;

@Data
@Builder
class MyUserPo {
    private Long id;
    private Date createTime;
    private Long age;
    private String userNick;
    private String userVerified;
}

@Data
@Builder
class MyUserBO {
    private Long id;
    private Date createTime;
    private Long age;
    private String Nick;
    private String userVerified;
}

@Mapper
interface IPersonMapper {
    IPersonMapper INSTANCT = Mappers.getMapper(IPersonMapper.class);
    @Mapping(source = "userNick", target = "Nick")
    MyUserBO po2bo(MyUserPo userPo);
}

public class Main {
    public static void main(String[] args) {
        MyUserPo userPo = MyUserPo.builder()
            .id(0L)
            .userNick("mapstruct")
            .userVerified("ok")
            .age(17L)
            .build();
        System.out.println("PO: " + userPo);
        MyUserBO userEntity = IPersonMapper.INSTANCT.po2bo(userPo);
        System.out.println("BO: " + userEntity);
    }
}

自定义处理

通过qualifiedByName@Named("addHa"),完成根据函数名字进行自定义处理

import lombok.Builder;
import lombok.Data;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Named;
import org.mapstruct.factory.Mappers;

import java.util.Date;

@Mapper
interface IPersonMapper {
    IPersonMapper INSTANCT = Mappers.getMapper(IPersonMapper.class);
    @Mapping(source = "userNick", target = "Nick", qualifiedByName = "addHa")
    MyUserBO po1bo(MyUserPo userPo);

    @Named("addHa")
    default String addHa(String source) {
        return source + ":addHa";
    }
}

public class Main {
    public static void main(String[] args) {
        MyUserPo userPo = MyUserPo.builder()
            .id(0L)
            .userNick("mapstruct")
            .userVerified("ok")
            .age(17L)
            .build();
        System.out.println("PO: " + userPo);
        MyUserBO userEntity = IPersonMapper.INSTANCT.po1bo(userPo);
        System.out.println("BO: " + userEntity);
    }
}

参考文献

告别BeanUtils,Mapstruct从入门到精通 - 掘金