MapStruct

应用背景:DO(业务实体对象),DTO(数据传输对象)。在一个成熟的工程中,尤其是现在的分布式系统中,应用与应用之间,还有单独的应用细分模块之后,DO一般不会让外部依赖,这时候需要在提供对外接口的模块里放 DTO 用于对象传输,也即是 DO 对象对内,DTO对象对外,DTO 可以根据业务需要变更,并不需要映射 DO 的全部属性。这种对象与对象之间的互相转换,就需要有一个专门用来解决转换问题的工具,毕竟每一个字段都 get/set 会很麻烦。MapStruct 就是这样的一个属性映射工具,只需要定义一个 Mapper 接口,MapStruct 就会自动实现这个映射接口,避免了复杂繁琐的映射实现。 

结论:两个类对象属性拷贝放弃org.springframework.beans下的BeanUtils.copyProperties,采用MapStruct 

MapStruct官网地址:https://mapstruct.org/

官方使用文档: https://mapstruct.org/documentation/installation/

使用mapStruct的时候需要先引入下述依赖,当前mapstruct的版本为最新版本1.5.0.Beta1

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <org.mapstruct.version>1.5.0.Beta1</org.mapstruct.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct</artifactId>
        <version>${org.mapstruct.version}</version>
    </dependency>

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13.1</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.assertj</groupId>
        <artifactId>assertj-core</artifactId>
        <version>3.6.2</version>
        <scope>test</scope>
    </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>
            </configuration>
        </plugin>
    </plugins>
</build>

 业务实体对象DO:

import java.util.Date;

/**
 * 实体类
 */
public class TbUser {

    private Integer id;

    private String name;

    private Integer age;

    private Date createTime;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public TbUser(Integer id, String name, Integer age, Date createTime) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.createTime = createTime;
    }
}

  业务实体对象DTO:

public class UserVo {
    private String userName;
    private Integer age;

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "UserVo{" +
                "userName='" + userName + '\'' +
                ", age=" + age +
                '}';
    }
}

映射关联类:

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;

@Mapper
public interface UserMapper {

    UserMapper INSTANCE = Mappers.getMapper( UserMapper.class );

    @Mapping(source = "name", target = "userName")
    @Mapping(source = "age", target = "age")
    UserVo toUserVo(TbUser user);
}

测试类: 

import java.util.Date;
import org.junit.Test;
import org.mapstruct.example.test.TbUser;
import org.mapstruct.example.test.UserMapper;
import org.mapstruct.example.test.UserVo;

public class MapperTest {

    @Test
    public void contextLoads(){
        TbUser user = new TbUser(2,"Morris", 5, new Date());
        UserVo userVo = UserMapper.INSTANCE.toUserVo(user);
        System.out.println(userVo.toString());
    }
}

 输出结果:

UserVo{userName='Morris', age=5}

特别提示: mapstruct与lombok进行整合的时候会报错,需慎用关联关系

与其它工具类的性能比较测试:

第一种:与spring-beans中的BeanUtils.copyProperties进行比较

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-beans</artifactId>
    <version>5.3.12</version>
</dependency>

 测试类:

import java.util.Date;
import org.junit.Test;
import org.mapstruct.example.test.TbUser;
import org.mapstruct.example.test.UserMapper;
import org.mapstruct.example.test.UserVo;
import org.springframework.beans.BeanUtils;

public class MapperTest {

    @Test
    public void contextLoads1(){
        for(int i=1;i<10000;i++){
            TbUser user = new TbUser(2,"Morris", 5, new Date());
            UserVo userVo = UserMapper.INSTANCE.toUserVo(user);
            System.out.println(userVo.toString());
        }
    }

    @Test
    public void contextLoads2(){
        for(int i=1;i<10000;i++){
            TbUser user = new TbUser(2,"Morris", 5, new Date());
            UserVo userVo = new UserVo();
            userVo.setUserName(user.getName());
            BeanUtils.copyProperties(user,userVo);
            System.out.println(userVo.toString());
        }
    }
}

上述测试结果为:使用MapStruct仅仅花费63ms,使用spring-beans时花费了184ms

第二种:与commons-beanutils中的BeanUtils.copyProperties进行比较

<dependency>
    <groupId>commons-beanutils</groupId>
    <artifactId>commons-beanutils</artifactId>
    <version>1.9.4</version>
</dependency>

 测试类:

import java.util.Date;
import org.apache.commons.beanutils.BeanUtils;
import org.junit.Test;
import org.mapstruct.example.test.TbUser;
import org.mapstruct.example.test.UserMapper;
import org.mapstruct.example.test.UserVo;

public class CustomerMapperTest {

    @Test
    public void contextLoads1(){
        for(int i=1;i<10000;i++){
            TbUser user = new TbUser(2,"Morris", 5, new Date());
            UserVo userVo = UserMapper.INSTANCE.toUserVo(user);
            System.out.println(userVo.toString());
        }
    }

    @Test
    public void contextLoads2() throws Exception{
        for(int i=1;i<10000;i++){
            TbUser user = new TbUser(2,"Morris", 5, new Date());
            UserVo userVo = new UserVo();
            userVo.setUserName(user.getName());
            BeanUtils.copyProperties(userVo,user);
            System.out.println(userVo.toString());
        }
    }
}

上述测试结果为:使用MapStruct仅仅花费66ms,使用spring-beans时花费了764ms

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值