栏目分类:
子分类:
返回
终身学习网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
终身学习网 > IT > 软件开发 > 后端开发 > Java

实体类转换工具 MapStruct,不要再使用BeanUtils了

Java 更新时间:发布时间: 百科书网 趣学号

目录

1、性能分析

2、什么是Mapstruct

4、普通使用方法

4.1 创建DO

4.2创建DTO

4.3创建一个基础的Mapstruct类

4.4创建映射器接口

5、spring依赖注入使用方法

6、总结

7、源码和官网


1、性能分析

在我们平时开发过程中,往往会涉及到,对象和对象直接的转化,而看到这个需求时直接想到的就是反射和BeanUtils工具,但是这个之间的效率往往是非常低的。

public class ReflectTest {

    
    private static final int LIMIT_NUM = 1;

    
    @Test
    public void beanUtil() {
        long start = System.currentTimeMillis();

        OrderDTO orderDto = new OrderDTO();
        orderDto.setName("mapstruct 测试");
        orderDto.setCost(12L);
        orderDto.setPrice("13");
        orderDto.setWeight(123L);
        orderDto.setIsDeleted(false);
        orderDto.setIsFinish(true);
        orderDto.setGmtCreat(LocalDateTime.now());
        orderDto.setGmtModified(LocalDateTime.now());

        ItemDTO itemDTO = new ItemDTO();
        itemDTO.setItemName("衬衫");
        itemDTO.setPrice(12L);
        orderDto.setItemList(Arrays.asList(itemDTO));


        for (int i = 0; i < LIMIT_NUM; i++) {
            final Order order = new Order();
            BeanUtils.copyProperties(orderDto, order);
        }

        long end = System.currentTimeMillis();
        System.out.println("BeanUtils耗时:"+(end - start ) + "ms");

        mapstruct();
    }

    
    @Test
    public void mapstruct() {
        long start = System.currentTimeMillis();

        OrderDTO orderDto = new OrderDTO();
        orderDto.setName("mapstruct 测试");
        orderDto.setCost(12L);
        orderDto.setPrice("13");
        orderDto.setWeight(123L);
        orderDto.setIsDeleted(false);
        orderDto.setIsFinish(true);
        orderDto.setGmtCreat(LocalDateTime.now());
        orderDto.setGmtModified(LocalDateTime.now());

        ItemDTO itemDTO = new ItemDTO();
        itemDTO.setItemName("衬衫");
        itemDTO.setPrice(12L);
        orderDto.setItemList(Arrays.asList(itemDTO));

        for (int i = 0; i < LIMIT_NUM; i++) {
            final Order order = new Order();
            OrderMapper.INSTANCE.updateOrder(orderDto, order);
        }

        long end = System.currentTimeMillis();
        System.out.println("mapstruct耗时:"+(end - start ) + "ms");
    }
}



平均结果:

BeanUtils耗时:150ms
mapstruct耗时:10ms

从上面可以看出BeanUtils和Mapstruct的性能差距还是蛮大的。

当然很多人也会说放射如果通过缓存性能能极大的提升,但是问题是,大部分的情况下我们是无法满足缓存的条件,而且这种反射往往比较麻烦,所以今天来看看Mapstruct这个技术。

2、什么是Mapstruct

原文

MapStruct is a code generator that greatly simplifies the implementation of mappings between Java bean types based on a convention over configuration approach.

The generated mapping code uses plain method invocations and thus is fast, type-safe and easy to understand.

Mapsturct 是一个通过配置公约的一种代码生成器,它大大简化了Java Bean类型之间的映射的实现,而且类型安全,性能高,使用简单。

3、准备工作

引入依赖,java11环境时

    
        11
        11
        1.3.1.Final
        3.6.1
            


        
            org.glassfish.jaxb
            jaxb-runtime
        
        
            org.projectlombok
            lombok
        
        
            org.mapstruct
            mapstruct
            ${mapstruct.version}
        
        
            org.mapstruct
            mapstruct-processor
            ${mapstruct.version}
            provided
        

4、普通使用方法

4.1 创建DO
package com.eagle.example.mapstruct.dataobject;

import lombok.Data;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;


@Data
public class Order implements Serializable {
    
    private String title;
    
    private Long price;
    
    private Long weight;
    
    private Long cost;
    
    List itemList;
    
    private String isDeleted;
    
    private Boolean isFinish;
    
    private String gmtCreat;
    
    private LocalDateTime gmtModified;
}
package com.eagle.example.mapstruct.dataobject;

import lombok.Data;


@Data
public class Item {
    private String itemName;
    private Long price;
}

4.2创建DTO
package com.eagle.example.mapstruct.dto;

import lombok.Data;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;


@Data
public class OrderDTO implements Serializable {
    
    private String name;
    
    private String price;
    
    private Long weight;
    
    private Long cost;
    
    private List itemList;
    
    private Boolean isDeleted;
    
    private Boolean isFinish;
    
    private LocalDateTime gmtCreat;
    
    private LocalDateTime gmtModified;
}
package com.eagle.example.mapstruct.dto;

import lombok.Data;


@Data
public class ItemDTO {
    private String itemName;
    private Long price;
}
package com.eagle.example.mapstruct.dto;

import lombok.Data;

import java.io.Serializable;


@Data
public class OrderInfoDTO implements Serializable {

    
    private String name;
    
    private String price;

}

4.3创建一个基础的Mapstruct类

可以编写一些基础方法和通用功能,因为随着Localdate的引入DO也都使用了Localdate类型,但是Mapstruct对Localdate支持比较弱,所以引入

package com.eagle.example.mapstruct.convert;



import org.mapstruct.Mapper;

import java.time.LocalDate;
import java.time.LocalDateTime;

@Mapper(imports = {LocalDateTime.class, LocalDate.class})
public interface baseMapstruct {
}

4.4创建映射器接口

当前例子是比较全的一种形态,所以很多不需要使用的自己酌情删除

package com.eagle.example.mapstruct.convert;


public class BooleanStrFormat {

    private static final String Y_CHAR = "Y";

    private static final String N_CHAR = "N";

    public String toStr(Boolean isDisable) {
        if (isDisable) {
            return Y_CHAR;
        } else {
            return N_CHAR;
        }
    }

    public Boolean toBoolean(String str) {
        if (str.equals(Y_CHAR)) {
            return true;
        } else {
            return false;
        }
    }
}
package com.eagle.example.mapstruct.convert;

import com.eagle.example.mapstruct.dataobject.Order;
import com.eagle.example.mapstruct.dto.OrderDTO;
import com.eagle.example.mapstruct.dto.OrderInfoDTO;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget;
import org.mapstruct.Mappings;
import org.mapstruct.ap.internal.util.Strings;
import org.mapstruct.factory.Mappers;

import java.util.List;


@Mapper(uses = BooleanStrFormat.class)
public interface OrderMapper extends baseMapstruct {

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

    String Y_CHAR = "Y";

    String N_CHAR = "N";

    
    @Mappings({
            @Mapping(source = "name", target = "title"),
            @Mapping(target = "gmtCreat", dateFormat = "yyyy-MM-dd HH:mm:ss"),
            @Mapping(target = "price", qualifiedByName = "toLong")
    })
    Order orderDto2Order(OrderDTO orderDTO);

    
    @Mappings({
            @Mapping(source = "title", target = "name"),
            @Mapping(target = "gmtCreat", dateFormat = "yyyy-MM-dd HH:mm:ss"),
            @Mapping(target = "price", qualifiedByName = "toStr")
    })
    OrderDTO order2OrderDto(Order order);

    default Long toLong(String price) {
        if (Strings.isEmpty(price)) {
            return 0L;
        } else {
            return Long.parseLong(price);
        }
    }

    default String toStr(Long price) {
        if (price != null) {
            return price.toString();
        } else {
            return "0";
        }
    }


    
    List orderDto2Order(List orderDTOList);

    
    @Mappings({
            @Mapping(source = "name", target = "title"),
            @Mapping(target = "gmtCreat", dateFormat = "yyyy-MM-dd HH:mm:ss"),
            @Mapping(target = "price", qualifiedByName = "toLong")
    })
    void updateOrder(OrderDTO orderDTO, @MappingTarget Order order);

    
    @Mappings({
            @Mapping(source = "orderInfoDTO.name", target = "title"),
            @Mapping(source = "orderDto.gmtCreat", target = "gmtCreat", dateFormat = "yyyy-MM-dd HH:mm:ss"),
            @Mapping(source = "orderInfoDTO.price", target = "price", qualifiedByName = "toLong")
    })
    Order getUserByOrderDTOAndOrderInfoDTO(OrderDTO orderDto, OrderInfoDTO orderInfoDTO);

    
    @Mappings({
            @Mapping(source = "orderInfoDTO.name", target = "title"),
            @Mapping(source = "orderDto.gmtCreat", target = "gmtCreat", dateFormat = "yyyy-MM-dd HH:mm:ss"),
            @Mapping(target = "price", source = "orderDto.price")
    })
    Order getUserByOrderDTOAndOrderInfoDTOChoicePrice(OrderDTO orderDto, OrderInfoDTO orderInfoDTO);
}

5、spring依赖注入使用方法
package com.eagle.example.mapstruct.convert;

import org.springframework.stereotype.Component;


@Component
public class SpringBooleanStrFormat {

    private static final String Y_CHAR = "Y";

    private static final String N_CHAR = "N";

    public String toStr(Boolean isDisable) {
        if (isDisable) {
            return Y_CHAR;
        } else {
            return N_CHAR;
        }
    }

    public Boolean toBoolean(String str) {
        if (str.equals(Y_CHAR)) {
            return true;
        } else {
            return false;
        }
    }
}
package com.eagle.example.mapstruct.convert;

import com.eagle.example.mapstruct.dataobject.Order;
import com.eagle.example.mapstruct.dto.OrderDTO;
import org.mapstruct.InjectionStrategy;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.ap.internal.util.Strings;

import java.util.List;


@Mapper(componentModel = "spring", injectionStrategy = InjectionStrategy.CONSTRUCTOR, uses = SpringBooleanStrFormat.class)
public interface SpringOrderMapper extends baseMapstruct {

    
    @Mappings({
            @Mapping(source = "name", target = "title"),
            @Mapping(target = "gmtCreat", dateFormat = "yyyy-MM-dd HH:mm:ss"),
            @Mapping(target = "price", qualifiedByName = "toLong")
    })
    Order orderDto2Order(OrderDTO orderDTO);

    
    @Mappings({
            @Mapping(source = "title", target = "name"),
            @Mapping(target = "gmtCreat", dateFormat = "yyyy-MM-dd HH:mm:ss"),
            @Mapping(target = "price", qualifiedByName = "toStr")
    })
    OrderDTO order2OrderDto(Order order);

    default Long toLong(String price) {
        if (Strings.isEmpty(price)) {
            return 0L;
        } else {
            return Long.parseLong(price);
        }
    }

    default String toStr(Long price) {
        if (price != null) {
            return price.toString();
        } else {
            return "0";
        }
    }


    
    List orderDto2Order(List orderDTOList);

}

6、总结

7、源码和官网

github:eagle-example: 项目例子集合

官网:MapStruct – Java bean mappings, the easy way!

转载请注明:文章转载自 www.051e.com
本文地址:http://www.051e.com/it/274851.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 ©2023-2025 051e.com

ICP备案号:京ICP备12030808号