(1). MapStruct介绍
MapStruct是一个属性映射工具,只需要定义一个Mapper接口,MapStruct就会自动实现这个映射接口,避免了复杂繁琐的映射实现. 在一个JavaWeb工程中会涉及到多种对象,po、vo、dto、entity、do、domain这些定义的对象运用在不同的场景模块中,这种对象与对象之间的互相转换,就需要有一个专门用来解决转换问题的工具.以前是通过反射的方法实现,但是,使用反射的时候都会影响到性能,再后来自己写装换器但是会很浪费时间,而且在添加新的字段的时候也要进行方法的修改.MapSturct是一个生成类型安全,高性能且无依赖的JavaBean映射代码的注解处理器.作为一个工具类,相比于手写,具有便捷,不容易出错的特点.
(2). MapStruct的使用
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<org.mapstruct.version>1.5.0.Beta1</org.mapstruct.version>
</properties>
<dependencies>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<!-- 指定注解的处理 -->
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
(3). 定义DTO
package org.mapstruct.example.dto;
import java.util.List;
public class CustomerDto {
public Long id;
public String customerName;
public List<OrderItemDto> orders;
} // end CustomerDto
package org.mapstruct.example.dto;
public class OrderItemDto {
public String name;
public Long quantity;
} // end OrderItemDto
(4). 定义DTO
package org.mapstruct.example.dto;
import java.util.Collection;
public class Customer {
private Long id;
private String name;
private Collection<OrderItem> orderItems;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Collection<OrderItem> getOrderItems() {
return orderItems;
}
public void setOrderItems(Collection<OrderItem> orderItems) {
this.orderItems = orderItems;
}
}// end Customer
package org.mapstruct.example.dto;
public class OrderItem {
private String name;
private Long quantity;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getQuantity() {
return quantity;
}
public void setQuantity(Long quantity) {
this.quantity = quantity;
}
} // end OrderItem
(5). 定义Mapper
package org.mapstruct.example.mapper;
import org.mapstruct.InheritInverseConfiguration;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.example.dto.Customer;
import org.mapstruct.example.dto.CustomerDto;
import org.mapstruct.factory.Mappers;
@Mapper(uses = { OrderItemMapper.class })
public interface CustomerMapper {
CustomerMapper MAPPER = Mappers.getMapper( CustomerMapper.class );
//
@Mapping(source = "orders", target = "orderItems")
@Mapping(source = "customerName", target = "name")
Customer toCustomer(CustomerDto customerDto);
@InheritInverseConfiguration
CustomerDto fromCustomer(Customer customer);
} // end CustomerMapper
package org.mapstruct.example.mapper;
import org.mapstruct.InheritInverseConfiguration;
import org.mapstruct.Mapper;
import org.mapstruct.example.dto.OrderItem;
import org.mapstruct.example.dto.OrderItemDto;
import org.mapstruct.factory.Mappers;
@Mapper
public interface OrderItemMapper {
OrderItemMapper MAPPER = Mappers.getMapper(OrderItemMapper.class);
OrderItem toOrder(OrderItemDto orderItemDto);
@InheritInverseConfiguration
OrderItemDto fromOrder(OrderItem orderItem);
} // end OrderItemMapper
(6). CustomerMapperTest
public class CustomerMapperTest {
@Test
public void testMapDtoToEntity() {
CustomerDto customerDto = new CustomerDto();
customerDto.id = 10L;
customerDto.customerName = "Filip";
OrderItemDto order1 = new OrderItemDto();
order1.name = "Table";
order1.quantity = 2L;
customerDto.orders = new ArrayList<>( Collections.singleton( order1 ) );
Customer customer = CustomerMapper.MAPPER.toCustomer( customerDto );
assertThat( customer.getId() ).isEqualTo( 10 );
assertThat( customer.getName() ).isEqualTo( "Filip" );
assertThat( customer.getOrderItems() )
.extracting( "name", "quantity" )
.containsExactly( tuple( "Table", 2L ) );
}
}
(7). 总结
优势就是自己不需要一个个的set/get方法的映射了,缺点就是:注解对代码有侵入性.