转载

吐血推荐| 一款好用的类转换工具

吐血推荐| 一款好用的类转换工具 戳蓝字「TopCoder 」关注我们哦!

常见的项目开发,应用与应用之间,还有单独的应用细分模块之后,DO 一般不会让外部依赖,这时候需要在提供对外接口的模块里放 DTO 用于对象传输,也即是 DO 对象对内,DTO对象对外,DTO 可以根据业务需要变更,并不需要映射 DO 的全部属性。MapStruct 就是这样的一个属性映射工具,只需要定义一个 Mapper 接口,MapStruct 就会自动实现这个映射接口,避免了复杂繁琐的映射实现。MapStruct官网地址:https://mapstruct.org。

MapStruct是一种类型安全的bean映射类生成java注释处理器。MapStruct 可以将某种类型的对象映射为另外一种类型,如将某个 DO(业务实体对象) 对象转换为 DTO(数据传输对象),除了单个类转换之外,MapStruct还支持多个类转换成一个类。MapStruc 使用方式比较简单,定义一个映射接口,声明映射方法,配上注解,MapSturct 就会实现此接口。

引入依赖:

<dependency>

<groupId>org.mapstruct</groupId>

<artifactId>mapstruct-jdk8</artifactId>

<version>1.2.0.Final</version>

</dependency>

<dependency>

<groupId>org.mapstruct</groupId>

<artifactId>mapstruct-processor</artifactId>

<version>1.2.0.Final</version>

</dependency>

示例代码如下:

package com.github.skyline;


import lombok.AllArgsConstructor;

import lombok.Data;

import lombok.NoArgsConstructor;

import org.mapstruct.*;

import org.mapstruct.factory.Mappers;


import java.util.Arrays;

import java.util.Date;

import java.util.List;


/**

* @author luoxiangnan

* @date 2019-10-16

*/

public class MapStructMain {


@Data

@NoArgsConstructor

@AllArgsConstructor

public static class PersonDO {

private Long id;

private Name name;

private Date date;

private Integer age;

private String innerImportInfo;


@Data

@AllArgsConstructor

public static class Name {

private String firstName;

private String lastName;

}

}


@Data

@NoArgsConstructor

@AllArgsConstructor

public static class PersonDTO {

long id; // 对应PersonDO.id,由于是Long转long,所以生成后的代码会自动判断PersonDO.id是否为null

private String firstName; // 对应PersonDO.name.firstName

private String lastName; // 对应PersonDO.name.lastName

private String name; // 对应PersonDO.name字段

private Date date;

private Integer outAge;

private String dateFormat;

private String dateFormat2;

private String innerImportInfo;


@Data

@AllArgsConstructor

public static class Address {

private String address;

}

}


@Mapper

public static interface PersonConverter {

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


/**

* 基本映射

*/

@Mappings({

@Mapping(target = "name", expression = "java(personDO.getName().getFirstName() + /":/" + personDO.getName().getLastName())"),

@Mapping(source = "name.firstName", target = "firstName"),

@Mapping(source = "name.lastName", target = "lastName"),

@Mapping(target = "dateFormat", expression = "java(org.apache.commons.lang3.time.DateFormatUtils.format(personDO.getDate(), /"yyyy-MM-dd HH:mm:ss/"))"),

@Mapping(source = "date", target = "dateFormat2", dateFormat = "yyyy-MM-dd HH:mm:ss"),

@Mapping(source = "age", target = "outAge"),

@Mapping(target = "innerImportInfo", ignore = true)

})

PersonDTO toPersonDTO(PersonDO personDO);


/**

* 基本映射,映射已有DTO

* @param personDO

* @param personDTO

*/

@InheritConfiguration(name = "toPersonDTO")

void toPersonDTOV2(PersonDO personDO, @MappingTarget PersonDTO personDTO);


List<PersonDTO> toPersonDTOList(List<PersonDO> personDOList);

}


@Mapper

public static interface Two2OneConverter {

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


@Data

static class A {

String orderNo = "xxxx";

}

@Data

static class B {

Long skuId = 11111L;

}

@Data

static class C {

String orderNo;

Long skuId;

}


@Mappings({

@Mapping(source = "a.orderNo", target = "orderNo"),

@Mapping(source = "b.skuId", target = "skuId")

})

C toPersonDTO(A a, B b);

}


public static void main(String[] args) {

PersonDO personDO = new PersonDO(1L, new PersonDO.Name("luo", "xiangnan"),

new Date(), 26, "内部机密信息,勿外传");


System.out.println(personDO);

System.out.println(PersonConverter.INSTANCE.toPersonDTO(personDO));


PersonDTO personDTO = new PersonDTO();

PersonConverter.INSTANCE.toPersonDTOV2(personDO, personDTO);

System.out.println(personDTO);


System.out.println(PersonConverter.INSTANCE.toPersonDTOList(Arrays.asList(personDO)));



// 多个类转成单个类

Two2OneConverter.C c = Two2OneConverter.INSTANCE.toPersonDTO(new Two2OneConverter.A(), new Two2OneConverter.B());

System.out.println(c);

}

}

上述代码编译之后,生成2个转换类,如下图:

吐血推荐| 一款好用的类转换工具

输出结果为:

MapStructMain.PersonDO(id=1, name=MapStructMain.PersonDO.Name(firstName=luo, lastName=xiangnan), date=Wed Oct 16 21:47:49 CST 2019, age=26, innerImportInfo=内部机密信息,勿外传)

MapStructMain.PersonDTO(id=1, firstName=luo, lastName=xiangnan, name=luo:xiangnan, date=Wed Oct 16 21:47:49 CST 2019, outAge=26, dateFormat=2019-10-16 21:47:49, dateFormat2=2019-10-16 21:47:49, innerImportInfo=null)

MapStructMain.PersonDTO(id=1, firstName=luo, lastName=xiangnan, name=luo:xiangnan, date=Wed Oct 16 21:47:49 CST 2019, outAge=26, dateFormat=2019-10-16 21:47:49, dateFormat2=2019-10-16 21:47:49, innerImportInfo=null)

[MapStructMain.PersonDTO(id=1, firstName=luo, lastName=xiangnan, name=luo:xiangnan, date=Wed Oct 16 21:47:49 CST 2019, outAge=26, dateFormat=2019-10-16 21:47:49, dateFormat2=2019-10-16 21:47:49, innerImportInfo=null)]

MapStructMain.Two2OneConverter.C(orderNo=xxxx, skuId=11111)

上述代码中,我们使用的是直接获取Mapper方法:

PersonConverter.INSTANCE.toPersonDTO(personDO)

除此之外,还可以和 Spring 结合,在 @Mapper 后面加入

componentModel="spring"

@Mapper

public static interface PersonConverter {

//

}

// 代码中直接使用 @Autowired private PersonConverter personConverter; 即可

原文  http://mp.weixin.qq.com/s?__biz=MzIwNTI2ODY5OA==&mid=2649938597&idx=2&sn=6795b8daf64955632e4ae91e9e582179
正文到此结束
Loading...