本月三號(hào),MapStruct 1.5.0 Final發(fā)布,本次正式版距離上次正式版發(fā)布已經(jīng)過去了快7年(上個(gè)正式版發(fā)布于2015年11月),此次發(fā)布除了修復(fù)了110多個(gè)bug外,還有以下新特性值得關(guān)注:
- 支持了Map到bean的轉(zhuǎn)換
- 支持更加完備的條件轉(zhuǎn)換(Conditional mapping)
- 支持子類之間的轉(zhuǎn)換(Support for subclass mapping)
1. 新增Map到Java bean的轉(zhuǎn)換(Mapping from Map to Bean)
如果我們有以下Java Bean
public class Customer { private Long id; private String name; //getters and setter omitted for brevity}
相應(yīng)的MapStruct代碼如下:
@Mapperpublic interface CustomerMapper { @Mapping(target = “name”, source = “customerName”) Customer toCustomer(Map map);}
那最終會(huì)生成類似如下的轉(zhuǎn)換代碼:
// GENERATED CODEpublic class CustomerMapperImpl implements CustomerMapper { @Override public Customer toCustomer(Map map) { // … if ( map.containsKey( “id” ) ) { customer.setId( Integer.parseInt( map.get( “id” ) ) ); } if ( map.containsKey( “customerName” ) ) { customer.setName( source.get( “customerName” ) ); } // … }}
不過需要注意,待轉(zhuǎn)換的Map的key必須是String類型的,否則,轉(zhuǎn)換代碼會(huì)跳過這個(gè)key
2. 更加完備的條件轉(zhuǎn)換(Conditional Mapping)
從1.5.0 Final版本之前,如果Java bean中含有hasXXX或者isXXX的這類方法(XXX是bean中的屬性名),則MapStruct生成的代碼中則會(huì)調(diào)用這類方法來判斷是否在轉(zhuǎn)換后的bean中是否包含原來的屬性,但是遺憾的是,大多數(shù)情況下,我們并不能直接修改原bean的代碼。基于此,1.5.0 Final版本引入了org.mapstruct.Condition注解來實(shí)現(xiàn)條件轉(zhuǎn)換。例如我們有如下轉(zhuǎn)換代碼:
@Mapperpublic interface CarMapper { CarDto carToCarDto(Car car); @Condition default boolean isNotEmpty(String value) { return value != null && !value.isEmpty(); }}
則Map Struct 1.5.0 Final生成的代碼是:
// GENERATED CODEpublic class CarMapperImpl implements CarMapper { @Override public CarDto carToCarDto(Car car) { if ( car == null ) { return null; } CarDto carDto = new CarDto(); if ( isNotEmpty( car.getOwner() ) ) { carDto.setOwner( car.getOwner() ); } // Mapping of other properties return carDto; }}
org.mapstruct.Condition除了作用到整個(gè)bean外還可以修飾具體的屬性值,實(shí)現(xiàn)bean屬性維度的條件轉(zhuǎn)換。
3. 增加對(duì)子類轉(zhuǎn)換的支持(Subclass Mapping)
假如有父類Fruit和兩個(gè)子類Apple和Banana,在新特性的支持下我們的轉(zhuǎn)換代碼可以寫的更加簡(jiǎn)潔:
@Mapperpublic interface FruitMapper { @SubclassMapping( source = AppleDto.class, target = Apple.class ) @SubclassMapping( source = BananaDto.class, target = Banana.class ) Fruit map( FruitDto source );}
如果Fruit是抽象類或者是接口,則會(huì)報(bào)編譯錯(cuò)誤。
原文鏈接:https://mp.weixin.qq.com/s/DuMBy5fqpldm8vxD-v_NpQ