MapStruct 代替BeanUtil 和ModelMapper

一、Object mapping 的技术分类:

运行期 反射调用set/get 或者是直接对成员变量赋值 。 该方式通过invoke执行赋值,实现时一般会采用beanutil, Javassist等开源库。这类的代表:Dozer,ModelMaper

编译期 动态生成set/get代码的class文件 ,在运行时直接调用该class文件。该方式实际上扔会存在set/get代码,只是不需要自己写了。 这类的代表:MapStruct,Selma,Orika ### 主要框架性能对比: 每秒钟执行的object mapping越多越好。  

MapStruct 与 Selma的对比: https://java.libhunt.com/project/mapstruct/vs/selma

MapStruct 与 ModelMapper的对比: https://java.libhunt.com/project/mapstruct/vs/modelmapper

综合比较性能、问题排查、文档、成熟度、扩展性等因素来考虑,MapStruct 是一个不错的选择; 

二、Maven依赖与配置:

<properties>
      <java.version>1.8</java.version>
      <org.mapstruct.version>1.1.0.Final</org.mapstruct.version>
</properties>
<dependency>
      <groupId>org.mapstruct</groupId>
      <artifactId>mapstruct-jdk8</artifactId> <!-- use mapstruct-jdk8 for Java 8 or higher -->
      <version>${org.mapstruct.version}</version>
</dependency>
<plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.5.1</version>
          <configuration>
              <source>${java.version}</source>
              <target>${java.version}</target>
              <encoding>${java.encoding}</encoding>
              <annotationProcessorPaths>
                  <path>
                      <groupId>org.mapstruct</groupId>
                      <artifactId>mapstruct-processor</artifactId>                       
                      <version>${org.mapstruct.version}</version>
                   </path>
               </annotationProcessorPaths>
           </configuration>
</plugin>


三、MapStruct的基本使用:

@Mapper(componentModel = "spring")
public interface MonitorAppGroupIdcDTOMapper {
    MonitorAppGroupIdcDTOMapper MAPPER = Mappers.getMapper(MonitorAppGroupIdcDTOMapper.class);
    void mapping(MonitorAppGroupIdcDTO source, @MappingTarget MonitorAppGroupIdcDTO dest);
}
编译后生成的部分代码结构:
@Component
public class MonitorAppGroupIdcDTOMapperImpl implements MonitorAppGroupIdcDTOMapper {
    public MonitorAppGroupIdcDTOMapperImpl() {
    }

    public void mapping(MonitorAppGroupIdcDTO source, MonitorAppGroupIdcDTO dest) {
        if(source != null) {
            dest.setId(source.getId());
            dest.setGmtCreate(source.getGmtCreate());
            ...
        }
    }
}

可以看出MapStruct还需要依赖对象的get/set方法,有时候编写一堆的get/set方法看上去很不美观,期望能通过自动生成的方式插入get/set方法,其解决方案是使用lombok。mapstrcut官网也有二者结合的例子: https://github.com/mapstruct/mapstruct/issues/510 Lombok带来的问题是,如果我们期望通过公有的get/set方法范围私有属性时,IDE会提示方法不存在,这个时候我们可以下载安装Intellij Idea中的”Lombok plugin”来解决,但是这种方案带来了一定的繁琐性。比较好的方式是,对于DO或者DTO中的属性,如果属性为私有属性,需要通过get/set方法来访问的,那么就手工生成get/set方法,如果属性本身为共有属性的,那么就可以借助Lombok来自动生成get/set方法了。

四、MapStruct的属性与方法:

1. @Mapper注解的componentModel属性

componentModel 属性用于指定自动生成的接口实现类的组件类型。这个属性支持四个值:

  • default: 这是默认的情况,mapstruct不使用任何组件类型, 可以通过Mappers.getMapper(Class)方式获取自动生成的实例对象。
  • cdi: the generated mapper is an application-scoped CDI bean and can be retrieved via @Inject
  • spring: 生成的实现类上面会自动添加一个@Component注解,可以通过Spring的 @Autowired方式进行注入
  • jsr330: 生成的实现类上会添加@javax.inject.Named 和@Singleton注解,可以通过 @Inject注解获取。
更多实例移步至:点击打开链接   点击打开链接

官网地址:点击打开链接

实例:

创建Car类:

public class Car {
 
    private String make;
    private int numberOfSeats;
    private CarType type;
 
    //constructor, getters, setters etc.
}

创建CarDTO类:

public class CarDto {
 
    private String make;
    private int seatCount;
    private String type;
 
    //constructor, getters, setters etc.
}

创建CarMapper:

@Mapper 
public interface CarMapper {
 
    CarMapper INSTANCE = Mappers.getMapper( CarMapper.class ); 
 
    @Mapping(source = "numberOfSeats", target = "seatCount")
    CarDto carToCarDto(Car car); 
}
创建CarMapperTest:

@Test
public void shouldMapCarToDto() {
    //given
    Car car = new Car( "Morris", 5, CarType.SEDAN );
 
    //when
    CarDto carDto = CarMapper.INSTANCE.carToCarDto( car );
 
    //then
    assertThat( carDto ).isNotNull();
    assertThat( carDto.getMake() ).isEqualTo( "Morris" );
    assertThat( carDto.getSeatCount() ).isEqualTo( 5 );
    assertThat( carDto.getType() ).isEqualTo( "SEDAN" );
}





  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值