MapStruct 结合spring使用,设定componentModel = "spring"即可,如下Mapper接口:
@Mapper(componentModel = "spring")public interface CarDtoMapper{ Car dtoToEntity(CarDto dto);}生成的映射代码如下,发现实现类上添加了@Component注解
@Generated( value = "org.mapstruct.ap.MappingProcessor", date = "2021-04-26T11:02:50+0800", comments = "version: 1.4.2.Final, compiler: IncrementalProcessingEnvironment from gradle-language-java-6.8.jar, environment: Java 1.8.0_211 (Oracle Corporation)")@Componentpublic class CarDtoMapperImpl implements CarDtoMapper { @Override public Car dtoToEntity(CarDto dto) { if ( dto == null ) { return null; } Car car = new Car(); car.setName( dto.getName() ); return car; }}mapstruct结合spring,在使用方式上主要是需要编写接口文件和定义函数所带来编码工作量:
InheritInverseConfiguration注解,如下@InheritInverseConfiguration(name = "dtoToEntity") CarDto entityToDto(Car dto);Car dtoMapToEntity(CarDto dto, @MappingTarget Car car)反向映射,同样需要添加如下方法
CarDto entityMapToDto(Car dto, @MappingTarget CarDto car);对于对象映射,有一种理想的使用方式,伪代码如下
Car car = mapper.map(dto, Car.class);// orCar car = new Car();mapper.map(dto, car);// 反向映射CarDto dto = mapper.map(entity, CarDto.class);// orCarDto dto = new CarDto();mapper.map(entity, dto);只使用mapper对象,就可以解决任何对象之间的映射。
官方地址如下: [https://github.com/mapstruct/mapstruct-spring-
extensions](https://links.jianshu.com/go?to=https%3A%2F%2Fgithub.com%2Fmapstruct%2Fmapstruct-
spring-extensions)
其思路是使用spring 的 Converter接口,官方用法如下
@Mapper(config = MapperSpringConfig.class)public interface CarMapper extends Converter<Car, CarDto> { @Mapping(target = "seats", source = "seatConfiguration") CarDto convert(Car car);} @ComponentScan("org.mapstruct.extensions.spring") @Component static class AdditionalBeanConfiguration { @Bean ConfigurableConversionService getConversionService() { return new DefaultConversionService(); } } @BeforeEach void addMappersToConversionService() { conversionService.addConverter(carMapper); conversionService.addConverter(seatConfigurationMapper); conversionService.addConverter(wheelMapper); conversionService.addConverter(wheelsMapper); conversionService.addConverter(wheelsDtoListMapper); } @Test void shouldKnowAllMappers() { then(conversionService.canConvert(Car.class, CarDto.class)).isTrue(); then(conversionService.canConvert(SeatConfiguration.class, SeatConfigurationDto.class)).isTrue(); then(conversionService.canConvert(Wheel.class, WheelDto.class)).isTrue(); then(conversionService.canConvert(Wheels.class, List.class)).isTrue(); then(conversionService.canConvert(List.class, Wheels.class)).isTrue(); } @Test void shouldMapAllAttributes() { // Given final Car car = new Car(); car.setMake(TEST_MAKE); car.setType(TEST_CAR_TYPE); final SeatConfiguration seatConfiguration = new SeatConfiguration(); seatConfiguration.setSeatMaterial(TEST_SEAT_MATERIAL); seatConfiguration.setNumberOfSeats(TEST_NUMBER_OF_SEATS); car.setSeatConfiguration(seatConfiguration); final Wheels wheels = new Wheels(); final ArrayList<Wheel> wheelsList = new ArrayList<>(); final Wheel wheel = new Wheel(); wheel.setDiameter(TEST_DIAMETER); wheel.setPosition(TEST_WHEEL_POSITION); wheelsList.add(wheel); wheels.setWheelsList(wheelsList); car.setWheels(wheels); // When final CarDto mappedCar = conversionService.convert(car, CarDto.class);}使用 mapstruct-spring-extensions,使用 ConfigurableConversionService,
虽然解决了使用同一个对象映射,但是代码量没有解决,同时,没有提供覆盖已有对象的使用方式
地址: [https://github.com/ZhaoRd/mapstruct-spring-
plus](https://links.jianshu.com/go?to=https%3A%2F%2Fgithub.com%2FZhaoRd%2Fmapstruct-
spring-plus)
这个项目参考了`mapstruct-spring-
extensions项目,同时使用APT技术,动态生成Mapper接口,解决编写接口的问题,提供IObejctMapper`接口,提供所有的map方法。
<properties> <org.mapstruct.version>1.4.2.Final</org.mapstruct.version> <io.github.zhaord.version>1.0.1.RELEASE</io.github.zhaord.version></properties>...<dependencies> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct</artifactId> <version>${org.mapstruct.version}</version> </dependency> <dependency> <groupId>io.github.zhaord</groupId> <artifactId>mapstruct-spring-plus-boot-starter</artifactId> <version>${io.github.zhaord.version}</version> </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> <path> <groupId>io.github.zhaord</groupId> <artifactId>mapstruct-spring-plus-processor</artifactId> <version>${io.github.zhaord.version}</version> </path> </annotationProcessorPaths> </configuration> </plugin> </plugins></build>dependencies { ... compile 'org.mapstruct:mapstruct:1.4.2.Final' compile 'io.github.zhaord:mapstruct-spring-plus-boot-starter:1.0.1.RELEASE' annotationProcessor 'org.mapstruct:mapstruct-processor:1.4.2.Final' testAnnotationProcessor 'org.mapstruct:mapstruct-processor:1.4.2.Final' // if you are using mapstruct in test code annotationProcessor 'io.github.zhaord:mapstruct-spring-plus-processor:1.0.1.RELEASE' testAnnotationProcessor 'io.github.zhaord:mapstruct-spring-plus-processor:1.0.1.RELEASE' // if you are using mapstruct in test code ...}使用代码如下
public enum CarType { SPORTS, OTHER}@Datapublic class Car { private String make; private CarType type;}@Data@AutoMap(targetType = Car.class)public class CarDto { private String make; private String type;}@ExtendWith(SpringExtension.class)@ContextConfiguration( classes = {AutoMapTests.AutoMapTestConfiguration.class})public class AutoMapTests { @Autowired private IObjectMapper mapper; @Test public void testDtoToEntity() { var dto = new CarDto(); dto.setMake("M1"); dto.setType("OTHER"); Car entity = mapper.map(dto, Car.class); assertThat(entity).isNotNull(); assertThat(entity.getMake()).isEqualTo("M1"); assertThat(entity.getCarType()).isEqualTo("OTHER"); } @ComponentScan("io.github.zhaord.mapstruct.plus") @Configuration @Component static class AutoMapTestConfiguration { }}@Mapper( config = AutoMapSpringConfig.class, uses = {})public interface CarDtoToCarMapper extends BaseAutoMapper<CarDto, Car> { @Override @Mapping( ignore = false ) Car map(final CarDto source); @Override @Mapping( ignore = false ) Car mapTarget(final CarDto source, @MappingTarget final Car target);}AutoMap注解,减少了重复代码的编写,尤其是接口文件和映射方法IObjectMapper接口即可,具体实现细节和调用方法,对客户端友好@Mapping注解,都可以使用@AutoMapField来完成字段的映射设置,因为@AutoMapField继承自@Mapping,比如字段名称不一致、跳过映射等原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。