mapstruct 对象转换器

2020-05-06   165 次阅读


今儿发现一款另外一款对象转换工具,研究了一下,发现比Spring提供的BeanUtils更加的方便,便记录一下使用方法。
使用方法也很简单,定义一个映射接口,声明映射方法,配上注解,MapStruct就会实现改接口。

引入mapstruct依赖

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

一对一映射

  • 定义实体类
    a、转的对象 App.java
@Data
public class App{
    private Long id;
    private String appId;
    private String appName;
    private String appContent;
}

b、 接受对象 AppDTO.java

@Data
public class AppDTO{
    private Long id;
    private String appId;
    private String appName;
    private String content;
}

  • 创建Mapper接口
@Mapper
//@Mapper(componentModel = "spring")
public interface AppConvert {

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

   /**
    * Entity转换为DTO
    * @param app
    * @return MerchantDTO
    */
   @Mappings({
           @Mapping(source = "appContent",target = "content")
   })
   AppDTO entity2dto(App app);

   /**
    * DTO转换为Entity
    * @param appDTO
    * @return Merchant
    */
   App dto2entity(AppDTO appDTO);

   /**
    * Entity List转换为DTO
    * @param appList
    * @return MerchantDTO
    */
   List<AppDTO> listentity2dto(List<App> appList);
}

在这里, 定义有两种方式,一种是@Mapper(componentModel = "spring"), 将该类注入到spring容器当中,使用时用@Autowire 注解表示使用。第二种是直接使用@Mapper注解,工具类内添加: AppConvert INSTANCE = Mappers.getMapper(AppConvert.class);,是用单例模式进行调用,调用时使用AppConvert .INSTANCE .方法名(参数)。

AppConvert 接口,定义了对象之间的转换和List之间的额转换,其中mapstruct提供的默认转换属性名相同的属性转换,当属性名不同时我们该如何转换呢? 例如AppDTO entity2dto(App app)方法,在方法名上添加@Mappings @Mapping 注解,通过指定原属性名和转换后的属性名,进行转换。这也让我觉得mapstrct比Spring提供的BeanUtils好用的一方面。

多对一映射

此时,又有新的需求,我向把两个对象的值,转到一个对象中,mapstruct能实现么?当然可以,mapstruct支持多对一的映射。例如:

a、需要转的类型

----------商品信息----------
@Data
public class GoodInfo {
    private Long id;
    private String title;
    private double price;
    private int order;
    private Long typeId;
}
----------商品类型----------
@Data
public class GoodType {
    private Long id;
    private String name;
    private int show;
    private int order;
}

b、接收类型

@Data
public class GoodInfoDTO {
    private String goodId;
    private String goodName;
    private double goodPrice;
    private String typeName;
}

3、 创建Mapper接口。

@Mapper(componentModel = "spring")
public interface GoodInfoMapper {
    @Mappings({
            @Mapping(source = "type.name",target = "typeName"),
            @Mapping(source = "good.id",target = "goodId"),
            @Mapping(source = "good.title",target = "goodName"),
            @Mapping(source = "good.price",target = "goodPrice")
    })
    GoodInfoDTO fromGoodInfoDTO(GoodInfo good, GoodType type);
}

通过传入的两个对象,返回需要的对象。
注意:
1、当source对象中,有相同的属性时,需在@Mapping中指定target接受的对象是哪个source的值,否则报错。
2、如果source中有null对象是, 返回的对象也是null对象

MapStruct注解

@Mapper:注解在接口、类上,这样 MapStruct 才会去实现该接口
      componentModel:该属性用于指定实现类的类型,有几个属性:
          default:默认,不使用任何组建类型,可以通过Mappers.getMapper(Class) 方式获取实例对象
          spring:在实现类上注解 @Component,可通过 @Autowired 方式注入
          jsr330:实现类上添加@javax.inject.Named 和@Singleton注解,可以通过 @Inject注解获取。
@Mappings:配置多个@Mapping
@Mapping:配置属性映射,若源对象属性与目标对象名字一致,会自动映射对应属性
    source:源属性、target:目标属性
    dateFormat:可将 String 到 Date 日期之间相互转换,通过SimpleDateFormat,该值为 SimpleDateFormat 的日期格式

Q.E.D.

知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议

一个萌新程序猿