Bean映射工具MapStruct介绍

Posted 诺浅

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Bean映射工具MapStruct介绍相关的知识,希望对你有一定的参考价值。

1. MapStruct是什么

MapStruct是一个功能强大且性能很高的Bean映射工具,项目开发中难免会涉及各种Bean的转换,DTO->VO->Entity。
市面上能做转换的框架很多,以前我们常用的可能是BeanUtils.copyProperties,其核心是在运行时根据反射动态赋值。动态方案的缺陷在于大量的反射调用,性能比较差,内存占用多,不适合特别高并发的应用场景。
而MapStruct通过注解,在编译时静态生成映射代码,其最终编译出来的代码和手写的代码在性能上完全一致,且有强大的注解等能力。如果你的IDE支持,甚至可以在编译后看到编译出来的映射代码,用来做check。

下面给出一张性能对比.

很明显MapStruct和JMapper的性能是最优异的

2. MapStruct如何使用


.如果报错可以尝试不要使用Lombok注解

2.1 基础使用

2.1.1 导包

<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct</artifactId>
    <version>1.4.2.Final</version>
</dependency>

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.7</version>
</dependency>

commons-lang3不是必须的,此处只是为了演示

2.1.2 写几个测试类
Person

package com.bxoon.mapstruct;


import java.util.Date;

public class Person 
    private Long id;
    private String name;
    private String email;
    private Date birthday;
    private User user;

    public Long getId() 
        return id;
    

    public void setId(Long id) 
        this.id = id;
    

    public String getName() 
        return name;
    

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

    public String getEmail() 
        return email;
    

    public void setEmail(String email) 
        this.email = email;
    

    public Date getBirthday() 
        return birthday;
    

    public void setBirthday(Date birthday) 
        this.birthday = birthday;
    

    public User getUser() 
        return user;
    

    public void setUser(User user) 
        this.user = user;
    

    public Person(Long id, String name, String email, Date birthday, User user) 
        this.id = id;
        this.name = name;
        this.email = email;
        this.birthday = birthday;
        this.user = user;
    

    public Person() 
    

PersonDTO

package com.bxoon.mapstruct;


import java.util.Date;

public class PersonDTO 
    private Long id;
    private String name;
    /**
     * 对应 Person.user.age
     */
    private Integer age;
    private String email;
    /**
     * 与 DO 里面的字段名称(birthDay)不一致
     */
    private Date birth;
    /**
     * 对 DO 里面的字段(birthDay)进行拓展,dateFormat 的形式
     */
    private String birthDateFormat;
    /**
     * 对 DO 里面的字段(birthDay)进行拓展,expression 的形式
     */
    private String birthExpressionFormat;

    public Long getId() 
        return id;
    

    public void setId(Long 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 String getEmail() 
        return email;
    

    public void setEmail(String email) 
        this.email = email;
    

    public Date getBirth() 
        return birth;
    

    public void setBirth(Date birth) 
        this.birth = birth;
    

    public String getBirthDateFormat() 
        return birthDateFormat;
    

    public void setBirthDateFormat(String birthDateFormat) 
        this.birthDateFormat = birthDateFormat;
    

    public String getBirthExpressionFormat() 
        return birthExpressionFormat;
    

    public void setBirthExpressionFormat(String birthExpressionFormat) 
        this.birthExpressionFormat = birthExpressionFormat;
    

    public PersonDTO(Long id, String name, Integer age, String email, Date birth, String birthDateFormat, String birthExpressionFormat) 
        this.id = id;
        this.name = name;
        this.age = age;
        this.email = email;
        this.birth = birth;
        this.birthDateFormat = birthDateFormat;
        this.birthExpressionFormat = birthExpressionFormat;
    

    public PersonDTO() 
    

public class User 
    private Integer age;

    public Integer getAge() 
        return age;
    

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

    public User(Integer age) 
        this.age = age;
    

    public User() 
    

PersonConverter

package com.bxoon.mapstruct;

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

import java.util.List;

@Mapper
public interface PersonConverter 
    PersonConverter INSTANCE = Mappers.getMapper(PersonConverter.class);
    @Mappings(
        @Mapping(source = "birthday", target = "birth"),
        @Mapping(source = "birthday", target = "birthDateFormat", dateFormat = "yyyy-MM-dd HH:mm:ss"),
        @Mapping(target = "birthExpressionFormat", expression = "java(org.apache.commons.lang3.time.DateFormatUtils.format(person.getBirthday(),\\"yyyy-MM-dd HH:mm:ss\\"))"),
        @Mapping(source = "user.age", target = "age"),
        @Mapping(target = "email", ignore = true)
    )
    PersonDTO domain2dto(Person person);

    List<PersonDTO> domain2dto(List<Person> people);

写一个测试类使用

package com.bxoon.shardingspheredemo;

import com.bxoon.mapstruct.Person;
import com.bxoon.mapstruct.PersonConverter;
import com.bxoon.mapstruct.PersonDTO;
import com.bxoon.mapstruct.User;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

public class PersonConverterTest 
    @Test
    public void test() 
        Person person = new Person(1L,"zhige","zhige.me@gmail.com",new Date(),new User(1));
        PersonDTO personDTO = PersonConverter.INSTANCE.domain2dto(person);
        assertNotNull(personDTO);
        assertEquals(personDTO.getId(), person.getId());
        assertEquals(personDTO.getName(), person.getName());
        assertEquals(personDTO.getBirth(), person.getBirthday());
        String format = DateFormatUtils.format(personDTO.getBirth(), "yyyy-MM-dd HH:mm:ss");
        assertEquals(personDTO.getBirthDateFormat(),format);
        assertEquals(personDTO.getBirthExpressionFormat(),format);

        List<Person> people = new ArrayList<>();
        people.add(person);
        List<PersonDTO> personDTOs = PersonConverter.INSTANCE.domain2dto(people);
        assertNotNull(personDTOs);

    

MapStruct还有很多种用法,比如可以把多个对象聚合转为一个对象,比如联合springboot的一起使用,详情见
https://www.cnblogs.com/jpfss/p/10898385.html

参考

https://www.cnblogs.com/jpfss/p/10898385.html
https://www.cnblogs.com/hollischuang/p/13469173.html

以上是关于Bean映射工具MapStruct介绍的主要内容,如果未能解决你的问题,请参考以下文章

学习笔记 - MapStruct 映射工具

学习笔记 - MapStruct 映射工具

干掉 BeanUtils!试试这款 Bean 自动映射工具,真心强大!

Bean 自动映射工具

Bean 自动映射工具

Bean 自动映射工具