MapStruct使用和原理分析

在代码开发中,经常会遇到不同实体类之间的字段copy,以前经常用到的有通过set赋值或者apache、spring的BeanUtils.copyProperties(),原生的set赋值随便速度比较快,但是当字段多的时候,就显得比较麻烦了,每个都要自己手动set一下值,而apache、spring的BeanUtils.copyProperties()可以解决这种字段比较多的情况,但是这种方式有个弊端,就是,字段的类型和名称都必须一样才可以,否则copy时会被忽略掉,还有个关键的问题就是apache的BeanUtils.copyProperties()效率比较低,spring的BeanUtils.copyProperties()效率还可以。直到接触了一种新的方式,使用MapStruct方式。

加入MapStruct的依赖jar包

    <properties>
        <mapstruct.version>1.2.0.Final</mapstruct.version>
    </properties>

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

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

创建实体类User

public class User {
    private Integer id;
    private String userName;
    private String desc;
    private Integer age;
    private Double salary;

    public Integer getId() {
        return id;
    }

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

    public String getUserName() {
        return userName;
    }

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

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }

    public Integer getAge() {
        return age;
    }

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

    public Double getSalary() {
        return salary;
    }

    public void setSalary(Double salary) {
        this.salary = salary;
    }
}

创建UserDTO类


public class UserDTO {
    private Integer id;
    private String userName;
    private Date createDate;
    private String remark;

    public Integer getId() {
        return id;
    }

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

    public String getUserName() {
        return userName;
    }

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

    public Date getCreateDate() {
        return createDate;
    }

    public void setCreateDate(Date createDate) {
        this.createDate = createDate;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }

    public UserDTO() {
    }

    @Override
    public String toString() {
        return "UserDTO{" +
                "id=" + id +
                ", userName='" + userName + '\'' +
                ", createDate=" + createDate +
                ", remark='" + remark + '\'' +
                '}';
    }

创建接口UserMapStruct

import org.mapstruct.MapMapping;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
@Mapper
public interface UserMapStruct {

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

    @Mappings({
        @Mapping(source = "desc",target = "remark")
    })
    public UserDTO userToDto(User user);
}

代码测试

public class TestUserMapStruct {

    public static void main(String[] args) {

        User user = new User();
        user.setId(1000);
        user.setAge(21);
        user.setDesc("测试复制工具");
        user.setSalary(400.44);
        user.setUserName("张三");

        UserDTO userDTO = UserMapStruct.INSTANCE.userToDto(user);
        System.out.println(userDTO.toString());

    }
}

输出结果

我们可以看到字段的值已经赋值到UserDTO上了。

MapStruct原理:

MapStruct是基于JSR 269的Java注解处理器,因此可以在命令行构建中使用(javac、Ant、Maven等等),也可以在IDE内使用。包括以下几个组件

org.mapstruct:mapstruct:包含了必要的注解,例如@Mapping;在Java 8或更高版本中,使用
org.mapstruct:mapstruct-jdk8,而不是利用Java 8中引入的语言进行改进。
org.mapstruct:mapstruct-processor:包含生成映射器实现的注解处理器

在编译过程中会根据自己的Mapper接口生成对应的实现类,比如上面定义的UserMapStruct类
 

猜你喜欢

转载自blog.csdn.net/dhj199181/article/details/111708060