高性能Java对象转换工具MapStruct

40 篇文章 1 订阅
22 篇文章 0 订阅

​欢迎光临我的博客查看最新文章: https://river106.cn

Java日常开发中经常涉及到各种对象的转换,如:VO、DO、DTO等,我们经常会借助工具来转换对象以减轻工作量、提升工作效率,如Apache的BeanUtils,Spring的BeanUtils、Cglib的BeanCopier、阿里的FastJson等,
本篇介绍另一个高性能的对象转换工具:MapStruct。

1、MapStruct简介

MapStruct是一个生成类型安全、高性能且无依赖的JavaBean映射代码的注解处理器。

官网: https://mapstruct.org/
github: https://github.com/mapstruct/mapstruct

2、MapStruct使用

2.1、引入依赖

<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>

和lombok一起使用的话,需要注意lombok的版本,否则可能出现问题, 如编译后的实现类未进行get set处理。

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.8</version>
</dependency>

使用Idea的话,开启注解处理:
File->Settings->Build,Execulion,Development->Complier->Annotation Processors
勾选Enable annotation processing

2.2、定义需要转换的类

@NoArgsConstructor
@AllArgsConstructor
@Data
public class Person {
    private Long id;
    private String name;
    private Integer age;
    private String email;
    private Date birthday;
}
@NoArgsConstructor
@AllArgsConstructor
@Data
@ToString
public class PersonDTO {
    private Long id;
    private String name;
    private Integer age;
    private String email;
    /**
     * 与 Person 的 birthDay 不一致
     */
    private Date birth;
    /**
     * 对 Person 的birthDay进行拓展, dateFormat的形式
     */
    private String birthDateFormat;

}

2.3、定义映射类

@Mapper
public interface PersonMapper {

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

    @Mappings({
            @Mapping(source = "birthday", target = "birth"),
            @Mapping(source = "birthday", target = "birthDateFormat", dateFormat = "yyyy-MM-dd HH:mm:ss"),
            @Mapping(target = "email", ignore = true)
    })
    PersonDTO convert(Person person);
}

@Mapper 只有在接口加上这个注解, MapStruct才会去实现该接口
@Mapper 里有个 componentModel 属性,主要是指定实现类的类型,一般用到两个:
default:默认,可以通过 Mappers.getMapper(Class) 方式获取实例对象
spring:在接口的实现类上自动添加注解 @Component,可通过 @Autowired 方式注入
@Mapping:属性映射,若源对象属性与目标对象名字一致,会自动映射对应属性
source:源属性
target:目标属性
dateFormat:String到Date日期之间相互转换,通过SimpleDateFormat进行日期格式化
ignore: 忽略这个字段
@Mappings:配置多个@Mapping

代码编译后,我们可以在target下看到自动生成的实现类PersonMapperImpl:

public class PersonMapperImpl implements PersonMapper {

    @Override
    public PersonDTO convert(Person person) {
        if ( person == null ) {
            return null;
        }

        PersonDTO personDTO = new PersonDTO();

        personDTO.setBirth( person.getBirthday() );
        if ( person.getBirthday() != null ) {
            personDTO.setBirthDateFormat( new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ).format( person.getBirthday() ) );
        }
        personDTO.setId( person.getId() );
        personDTO.setName( person.getName() );

        return personDTO;
    }
}

2.4、测试

public class PersonConverterTest {

    public static void main(String[] args) {
        Person person = new Person(1L, "river106", "xxx@gmail.com", new Date());
        PersonDTO personDTO = PersonMapper.INSTANCE.convert(person);
        System.out.println(personDTO);
    }
}

2.5、交由Spring管理

添加spring相关依赖:

 <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.1.5.RELEASE</version>
</dependency>

新增转换类PersonMapperSpring,@Mapper注解componentModel属性改为spring;

@Mapper(componentModel = "spring")
public interface PersonMapperSpring {

    @Mappings({
            @Mapping(source = "birthday", target = "birth"),
            @Mapping(source = "birthday", target = "birthDateFormat", dateFormat = "yyyy-MM-dd HH:mm:ss"),
            @Mapping(target = "email", ignore = true)
    })
    PersonDTO convert(Person person);
}

测试:

@Configuration
@ComponentScan(value = "cn.river.mapstruct")
public class PersonConverterSpringTest {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context =
                new AnnotationConfigApplicationContext(PersonConverterSpringTest.class);
        Person person = new Person(1L, "river106", "xxx@gmail.com", new Date());
        PersonMapperSpring bean = context.getBean(PersonMapperSpring.class);
        PersonDTO personDTO = bean.convert(person);
        System.out.println(personDTO);
    }
}

3、和其他转换工具性能对比

使用如上简单对象,转换1000000次结果如下(时间单位:毫秒):

fastjson :2862
springBeanUtils :495
beanCopier :122
mapstruct :16

从测试结果来看,MapStruct转换性能是最好的。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值