龙空技术网

MapStruct快速使用与不同场景的特性用法

Mirson架构之道 251

前言:

眼前姐妹们对“javac结构体”大致比较关切,姐妹们都需要知道一些“javac结构体”的相关资讯。那么小编同时在网络上汇集了一些有关“javac结构体””的相关知识,希望你们能喜欢,兄弟们快快来了解一下吧!

一、MapStruct与各主流对象映射框架性能对比

MapStruct是一款高性能的对象映射框架,采用JSR269注解处理器,支持可配置化、扩展性强。

MapStruct的高性能得益于预生成方式,采用原生Getter/Setter方法进行赋值,不会产生额外开销损耗。

二、MapStruct快速使用

通过示例,将AutoDispatch对象转换为AutoDispatchVO对象,学习如何通过MapStruct实现对象的转换。

1.集成MapStruct组件依赖:

<dependency>    <groupId>org.mapstruct</groupId>    <artifactId>mapstruct</artifactId>    <version>1.3.0.Final</version></dependency><dependency>    <groupId>org.mapstruct</groupId>    <artifactId>mapstruct-processor</artifactId>    <version>1.3.0.Final</version></dependency>

2.需转换的源对象

OrderSource:

@Datapublic class OrderSource implements Serializable {    private static final long serialVersionUID = 1L;    /**     * 订单明细数据     */    private List<OrderDetailSource> orderDetailList;    /**     * 订单编号数组     */    private String[] orderNumbers;    /**     *  订单编号     */    private String orderNo;    /**     * 订单ID     */    private Long orderId;    /**     * 创建日期     */    private Date createDate;    /**     * 账户编号     */    private String accountNo;}

3.需转换的目标对象

OrderTarget:

@Datapublic class OrderTarget implements Serializable {    private static final long serialVersionUID = 1L;    /**     * 订单明细数据     */    private List<OrderDetailSource> orderDetailList;    /**     * 订单编号数组     */    private String[] orderNumbers;    /**     *  订单编号     */    private String orderNumber;    /**     * 订单ID     */    private Long orderId;    /**     * 创建日期     */    private String createDate;    /**     * 账户编号     */    private String accountNo;}

4.映射配置接口

OrderConvert:

@Mapper(componentModel = "spring")public interface OrderConvert {    /**     * 定义实例     */    OrderConvert INSTANCE = Mappers.getMapper(OrderConvert.class);    /**     *  定义转换接口     * @param orderSource     * @return     */    OrderTarget copy(OrderSource orderSource);}

5.进行转换

编写测试用例:

	@Test    public void test() {        // 1. 定义订单明细对象1        OrderDetailSource detail1 = new OrderDetailSource();        detail1.setAddress("广东省深圳市宝安区1");        detail1.setCustomerName("customerName1");        // 2. 定义订单明细对象2        OrderDetailSource detail2 = new OrderDetailSource();        detail2.setAddress("广东省深圳市宝安区2");        detail2.setCustomerName("customerName2");        List<OrderDetailSource> orderDetailList = new ArrayList<>();        orderDetailList.add(detail1);        orderDetailList.add(detail2);        // 3. 创建需要转换的源对象        OrderSource order = new OrderSource();        order.setOrderNumbers(new String[]{"order001", "order002", "order003"});        order.setOrderNo("order001");        order.setOrderId(100001L);        order.setAccountNo("ACC0001");        order.setOrderDetailList(orderDetailList);        order.setCreateDate(new Timestamp(System.currentTimeMillis()));        // 4. 调用映射配置接口, 将OrderSource对象进行转换        OrderTarget orderTarget = OrderConvert.INSTANCE.copy(order);        // 5. 打印结果,查看验证数据        System.out.println(orderTarget);    }

可以看到,能够正确转换,包含子对象数据:

至此, 已经完成掌握MapStruct的初步使用。

三、MapStruct的特性使用

1.为什么MapStruct具备高性能从上面的示例中, 搜寻工程,会生成一个OrderConvertImpl实现类, 反编译其代码:

@Generated(    value = "org.mapstruct.ap.MappingProcessor",    date = "2021-10-15T16:16:06+0800",    comments = "version: 1.2.0.Final, compiler: javac, environment: Java 1.8.0_171 (Oracle Corporation)")@Componentpublic class OrderConvertImpl implements OrderConvert {    @Override    public OrderTarget copy(OrderSource orderSource) {        if ( orderSource == null ) {            return null;        }        OrderTarget orderTarget = new OrderTarget();        orderTarget.setOrderNumber( orderSource.getOrderNo() );        List<OrderDetailSource> list = orderSource.getOrderDetailList();        if ( list != null ) {            orderTarget.setOrderDetailList( new ArrayList<OrderDetailSource>( list ) );        }        else {            orderTarget.setOrderDetailList( null );        }        String[] orderNumbers = orderSource.getOrderNumbers();        if ( orderNumbers != null ) {            orderTarget.setOrderNumbers( Arrays.copyOf( orderNumbers, orderNumbers.length ) );        }        orderTarget.setOrderId( orderSource.getOrderId() );        orderTarget.setAccountNo( orderSource.getAccountNo() );        orderTarget.setCreateDate( com.mirson.mapstruct.test.ConvertUtil.dateToStr(orderSource.getCreateDate()) );        return orderTarget;    }}

可以看到, 内部是针对性的适配, 采用原生getter/setter方法进行属性复制。

如果没有生成此代码或更改代码后不生效,可执行编译命令重新生成:maven clean compile

2.属性类型不一致该如何处理

示例:将Date类型转换为String类型

源对象的createDate为Date类型

@Datapublic class OrderSource implements Serializable {	...	/**     * 创建日期     */    private Date createDate;}

目标对象的createDate为字符串类型

@Datapublic class OrderTarget implements Serializable {	...	/**     * 创建日期     */    private String createDate;}

映射配置接口增加:

@Mapperpublic interface OrderConvert {	...	/**     *  定义转换接口     * @param dispatch     * @return     */    @Mappings({            @Mapping(target = "createDate", expression = "java(com.mirson.mapstruct.test.ConvertUtil.dateToStr(orderSource.getCreateDate()))"),    })    OrderTarget copy(OrderSource orderSource);}

增加Mapping映射,指定转化的接口以及参数信息。

转换接口:

public class ConvertUtil {    /**     *  将日期类型转换为字符串类型     * @param date     * @return     */     public static String dateToStr(Date date){         if(null != date) {             DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");             Instant instant = date.toInstant();             LocalDateTime ldt = instant.atOffset(ZoneOffset.UTC).toLocalDateTime();             return format.format(ldt);         }         return null;     }}

运行之后, 可以看到createDate按照指定格式转换为字符串:

3.字段名不一致如何处理

源对象:

@Datapublic class OrderSource implements Serializable {	...	/**     * 调度编号     */    private String dispatchNo;}

目标对象:

@Datapublic class OrderTarget implements Serializable {	...	/**     * 调度编号     */    private String dispatchNumber;}

映射配置接口:

@Mapperpublic interface OrderConvert {	...	/**     *  定义转换接口     * @param dispatch     * @return     */    @Mappings({            @Mapping(source = "orderNo", target = "orderNumber"),    })    OrderTarget copy(OrderSource orderSource);}

执行结果:

4.支持Spring容器管理

在项目中, 如果想交给Spring 容器管理,可以在@Mapper注解中加入componentModel = "spring",则可以通过service注入方式进行使用。

@Mapper(componentModel = "spring")public interface OrderConvert {...}

标签: #javac结构体