对于JAVA开发时,不同DTO、BO、PO、VO对象的转换是一个问题。MapStruct可以帮助开发者快速的进行类型转换,比如快速的将一个VO转为DTO。
SPringboot集成MapStruct
首先在Sprongboot项目的pom文件中引入MapStruct的依赖。版本兼容性问题: 使用不兼容的MapStruct版本可能导致内部处理器错误。
<!--MapStruct 依赖-->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.4.1.Final</version>
</dependency>
<!--MapStruct 注解处理器-->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.4.1.Final</version>
</dependency>
接着引入lombok的依赖。
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
测试用例:假设有一个Person类和一个Adderss类。目标是要将Person类和Adderss类的属性数据全部转入到DeliverAdderss类中。 首先定义一个AddressMapper接口。
@Mapper
public interface AddressMapper {
//获取AddressMapper的实现类。实现类是编译时动态生成的。生成后的实现类会存放在target目录下。
AddressMapper INSTANCE = Mappers.getMapper(AddressMapper.class);
//定义将Person类和Address类映射到DeliveryAddress类的具体细节
@Mappings(
{
@Mapping(source = "person.description", target = "description"),
@Mapping(source = "address.houseNo", target = "houseNumber")
}
)
//这个转换方法将Person和Address对象转换为DeliveryAddress对象。只需要声明这个方法即可。具体实现会在AddressMapper接口的动态实现类中
DeliveryAddress personAndAddressToDeliveryAddressDto(Person person, Address address);
}
再编写一个单元测试。
@SpringBootTest
class MapstructApplicationTests {
@Test
void contextLoads() {
Person person = new Person();
person.setFirstName("John");
person.setLastName("Doe");
person.setHeight(180);
person.setDescription("I'm a person");
Address address = new Address();
address.setStreet("Street");
address.setZipCode(12345);
address.setHouseNo(123);
address.setDescription("I'm an address");
DeliveryAddress deliveryAddress = AddressMapper.INSTANCE.personAndAddressToDeliveryAddressDto(person, address);
System.out.println(deliveryAddress);
}
输出转化后deliveryAddress的结果:
DeliveryAddress(firstName=John, lastName=Doe, height=180, street=Street, zipCode=12345, houseNumber=123, description=I'm a person)
在target目录中可以找到转换工具MapStruct为AddressMapper编译时动态生成的实现类。实现类中实现了personAndAddressToDeliveryAddressDto这个方法。
public class AddressMapperImpl implements AddressMapper {
@Override
public DeliveryAddress personAndAddressToDeliveryAddressDto(Person person, Address address) {
if ( person == null && address == null ) {
return null;
}
DeliveryAddress deliveryAddress = new DeliveryAddress();
if ( person != null ) {
deliveryAddress.setDescription( person.getDescription() );
deliveryAddress.setFirstName( person.getFirstName() );
deliveryAddress.setLastName( person.getLastName() );
deliveryAddress.setHeight( person.getHeight() );
}
if ( address != null ) {
deliveryAddress.setHouseNumber( address.getHouseNo() );
deliveryAddress.setStreet( address.getStreet() );
deliveryAddress.setZipCode( address.getZipCode() );
}
return deliveryAddress;
}
}