mapstract实体转换工具

什么mapSturct

mapSturct 是一个生成类型安全, 高性能且无依赖的 JavaBean 映射代码的注解处理器(annotation processor)。通过动态生成代码实现,使代码易于调试和美观,

官方文档:https://mapstruct.org/documentation/stable/reference/html/#mapping-composition

引入POM

   <properties>
       <org.mapstruct.version>1.2.0.CR1</org.mapstruct.version>
    </properties>
    <dependencies>
        <!--mapStruct依赖-->
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct-jdk8</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>

 

简单使用

@Mapper
public interface PurchasePayableBillConvert {
    PurchasePayableBillConvert INSTANCE = Mappers.getMapper(PurchasePayableBillConvert.class);

    BillAdjustTypeItemSumDTO toBillAdjustTypeItemSumDTO(PurchasePayableBillAdjustLogDTO purchasePayableBillAdjustLogDTO);
    List<BillAdjustTypeItemSumDTO> toBillAdjustTypeItemSumDTOs(List<PurchasePayableBillAdjustLogDTO> purchasePayableBillAdjustLogDTOs);
    BillAdjustTypeItemSumDTO toBillAdjustTypeItemSumDTO(PurchasePayableBillAdjustLog purchasePayableBillAdjustLog);

}

 

与Spring整合

//此注解在自动生成实现类会打上@Comment注解 我们只需要让Spring扫描就行了
@Mapper(componentModel = "spring")
public interface MemberGradeConvert {
public MemberGradeEntity editReqDtOToPo(EditReqDtO editReqDtO); }

以上面为例自动在targer目录生成实现类

@Component
public class MemberGradeConvertImpl implements MemberGradeConvert {
    public MemberGradeConvertImpl() {
    }

    public MemberGradeEntity editReqDtOToPo(EditReqDtO editReqDtO) {
        if (editReqDtO == null) {
            return null;
        } else {
            MemberGradeEntity memberGradeEntity = new MemberGradeEntity();
            memberGradeEntity.setId(editReqDtO.getId());
            memberGradeEntity.setName(editReqDtO.getName());
            memberGradeEntity.setPoints(editReqDtO.getPoints());
            memberGradeEntity.setDiscountRate(editReqDtO.getDiscountRate());
            memberGradeEntity.setStatus(editReqDtO.getStatus());
            memberGradeEntity.setMerchantId(editReqDtO.getMerchantId());
            return memberGradeEntity;
        }
    }

}

多个组成一个VO

@Mapper(componentModel = "spring")
public interface CouponConvert {
    @Mapping(source = "couponCode.id", target = "couponCodeId")
    @Mapping(source = "couponCode.used", target = "used")
    @Mapping(source = "couponCode.usedDate", target = "usedDate")
    @Mapping(source = "couponCode.receiveDate", target = "receiveDate")
    @Mapping(source = "couponRo.enable", target = "enable")
    @Mapping( target = "expireDate",expression = "java(CouponConvert.getMaxDate(couponCode.getUsageEndDate(), couponRo==null?null:couponRo.getUsageEndDate()))")
    public FindUserCouponsResDto couponCodeAndCouponRoToFindUserCouponsResDto(CouponCode couponCode, CouponRo couponRo);

    static Timestamp getMaxDate(Timestamp date1, Timestamp date2){
        if(date1==null){
            return  date2;
        }
        if(date2==null){
            return date1;
        }
        return date1.getTime()>date2.getTime()?date1:date2;
    }
}

自动生成实现

@Component
public class CouponConvertImpl implements CouponConvert {

    @Override
    public FindUserCouponsResDto couponCodeAndCouponRoToFindUserCouponsResDto(CouponCode couponCode, CouponRo couponRo) {
        if ( couponCode == null && couponRo == null ) {
            return null;
        }

        FindUserCouponsResDto findUserCouponsResDto = new FindUserCouponsResDto();

        if ( couponCode != null ) {
            findUserCouponsResDto.setCouponCodeId( couponCode.getId() );
            findUserCouponsResDto.setReceiveDate( couponCode.getReceiveDate() );
            findUserCouponsResDto.setUsedDate( couponCode.getUsedDate() );
            findUserCouponsResDto.setUsed( couponCode.isUsed() );
        }
        if ( couponRo != null ) {
            if ( couponRo.getEnable() != null ) {
                findUserCouponsResDto.setEnable( couponRo.getEnable() );
            }
        }
        findUserCouponsResDto.setExpireDate( CouponConvert.getMaxDate(couponCode.getUsageEndDate(), couponRo==null?null:couponRo.getUsageEndDate()) );

        return findUserCouponsResDto;
    }
}

简单的条件处理 

  @Mapping(source = "couponCode.id", target = "couponCodeId")
    @Mapping(source = "couponCode.used", target = "used")
    @Mapping(source = "couponCode.usedDate", target = "usedDate")
    @Mapping(source = "couponCode.receiveDate", target = "receiveDate")
    @Mapping(source = "couponRo.enable", target = "enable")
    @Mapping(target = "amount", expression = "java(couponCode.getRanAmount()!=null?couponCode.getRanAmount():couponRo.getAmount())")
    @Mapping(target = "expireDate", expression = "java(couponRo.getUsageCountDownDays()!=null?couponCode.getUsageEndDate():couponRo.getUsageEndDate())")
    public FindUserCouponCodeByIdResDto couponCodeRoAndCouponRoToFindUserCouponCodeByIdResDto(CouponCodeRo couponCode, CouponRo couponRo);

转换后

   @Override
    public FindUserCouponCodeByIdResDto couponCodeRoAndCouponRoToFindUserCouponCodeByIdResDto(CouponCodeRo couponCode, CouponRo couponRo) {
        if ( couponCode == null && couponRo == null ) {
            return null;
        }

        FindUserCouponCodeByIdResDto findUserCouponCodeByIdResDto = new FindUserCouponCodeByIdResDto();

        if ( couponCode != null ) {
            findUserCouponCodeByIdResDto.setCouponCodeId( couponCode.getId() );
            findUserCouponCodeByIdResDto.setReceiveDate( couponCode.getReceiveDate() );
            findUserCouponCodeByIdResDto.setUsedDate( couponCode.getUsedDate() );
            findUserCouponCodeByIdResDto.setUsed( couponCode.isUsed() );
        }
        if ( couponRo != null ) {
            findUserCouponCodeByIdResDto.setEnable( couponRo.getEnable() );
        }
        findUserCouponCodeByIdResDto.setAmount( couponCode.getRanAmount()!=null?couponCode.getRanAmount():couponRo.getAmount() );
        findUserCouponCodeByIdResDto.setExpireDate( couponRo.getUsageCountDownDays()!=null?couponCode.getUsageEndDate():couponRo.getUsageEndDate() );

        return findUserCouponCodeByIdResDto;
    }
}

 

复杂的表达式 

@Mapper(componentModel = "spring")
public interface CouponConvert {
    @Mapping(source = "couponCode.id", target = "couponCodeId")
    @Mapping(source = "couponCode.used", target = "used")
    @Mapping(source = "couponCode.usedDate", target = "usedDate")
    @Mapping(source = "couponCode.receiveDate", target = "receiveDate")
    @Mapping(source = "couponRo.enable", target = "enable")
    @Mapping( target = "expireDate",expression = "java(CouponConvert.getMaxDate(couponCode.getUsageEndDate(), couponRo==null?null:couponRo.getUsageEndDate()))")
    public FindUserCouponsResDto couponCodeAndCouponRoToFindUserCouponsResDto(CouponCode couponCode, CouponRo couponRo);

    static Timestamp getMaxDate(Timestamp date1, Timestamp date2){
        if(date1==null){
            return  date2;
        }
        if(date2==null){
            return date1;
        }
        return date1.getTime()>date2.getTime()?date1:date2;
    }
}

转换后

@Component
public class CouponConvertImpl implements CouponConvert {

    @Override
    public FindUserCouponsResDto couponCodeAndCouponRoToFindUserCouponsResDto(CouponCode couponCode, CouponRo couponRo) {
        if ( couponCode == null && couponRo == null ) {
            return null;
        }

        FindUserCouponsResDto findUserCouponsResDto = new FindUserCouponsResDto();

        if ( couponCode != null ) {
            findUserCouponsResDto.setCouponCodeId( couponCode.getId() );
            findUserCouponsResDto.setReceiveDate( couponCode.getReceiveDate() );
            findUserCouponsResDto.setUsedDate( couponCode.getUsedDate() );
            findUserCouponsResDto.setUsed( couponCode.isUsed() );
        }
        if ( couponRo != null ) {
            if ( couponRo.getEnable() != null ) {
                findUserCouponsResDto.setEnable( couponRo.getEnable() );
            }
        }
        findUserCouponsResDto.setExpireDate( CouponConvert.getMaxDate(couponCode.getUsageEndDate(), couponRo==null?null:couponRo.getUsageEndDate()) );

        return findUserCouponsResDto;
    }
}

一对多

    @Mapping(target = "batchSoaGiveOutCouponItems",expression ="java(validateSendCouponItemReqVoToBatchSoaGiveOutCouponItem(validateSendCouponReqVo.getValidateSendCouponItemReqVos()))")
    public BatchSoaGiveOutCouponRequestVo validateSendCouponReqVoToBatchSoaGiveOutCouponRequestVo(ValidateSendCouponReqVo validateSendCouponReqVo);

    public List<BatchSoaGiveOutCouponRequestVo.BatchSoaGiveOutCouponItem> validateSendCouponItemReqVoToBatchSoaGiveOutCouponItem(List<ValidateSendCouponReqVo.ValidateSendCouponItemReqVo> validateSendCouponItemReqVos);
    @Mapping(target = "couponReceiveChannel",ignore = true)//忽略set
    public BatchSoaGiveOutCouponRequestVo.BatchSoaGiveOutCouponItem validateSendCouponItemReqVoToBatchSoaGiveOutCouponItem(ValidateSendCouponReqVo.ValidateSendCouponItemReqVo validateSendCouponItemReqVos);

转换

@Component
public class CouponConvertImpl implements CouponConvert {

    @Override
    public BatchSoaGiveOutCouponRequestVo validateSendCouponReqVoToBatchSoaGiveOutCouponRequestVo(ValidateSendCouponReqVo validateSendCouponReqVo) {
        if ( validateSendCouponReqVo == null ) {
            return null;
        }

        BatchSoaGiveOutCouponRequestVo batchSoaGiveOutCouponRequestVo = new BatchSoaGiveOutCouponRequestVo();

        batchSoaGiveOutCouponRequestVo.setBatchSoaGiveOutCouponItems( validateSendCouponItemReqVoToBatchSoaGiveOutCouponItem(validateSendCouponReqVo.getValidateSendCouponItemReqVos()) );

        return batchSoaGiveOutCouponRequestVo;
    }

    @Override
    public List<BatchSoaGiveOutCouponItem> validateSendCouponItemReqVoToBatchSoaGiveOutCouponItem(List<ValidateSendCouponItemReqVo> validateSendCouponItemReqVos) {
        if ( validateSendCouponItemReqVos == null ) {
            return null;
        }

        List<BatchSoaGiveOutCouponItem> list = new ArrayList<BatchSoaGiveOutCouponItem>( validateSendCouponItemReqVos.size() );
        for ( ValidateSendCouponItemReqVo validateSendCouponItemReqVo : validateSendCouponItemReqVos ) {
            list.add( validateSendCouponItemReqVoToBatchSoaGiveOutCouponItem( validateSendCouponItemReqVo ) );
        }

        return list;
    }

    @Override
    public BatchSoaGiveOutCouponItem validateSendCouponItemReqVoToBatchSoaGiveOutCouponItem(ValidateSendCouponItemReqVo validateSendCouponItemReqVos) {
        if ( validateSendCouponItemReqVos == null ) {
            return null;
        }

        BatchSoaGiveOutCouponItem batchSoaGiveOutCouponItem = new BatchSoaGiveOutCouponItem();

        batchSoaGiveOutCouponItem.setUserId( validateSendCouponItemReqVos.getUserId() );
        batchSoaGiveOutCouponItem.setUserMobile( validateSendCouponItemReqVos.getUserMobile() );
        batchSoaGiveOutCouponItem.setCouponId( validateSendCouponItemReqVos.getCouponId() );
        batchSoaGiveOutCouponItem.setMemberId( validateSendCouponItemReqVos.getMemberId() );
        batchSoaGiveOutCouponItem.setQuantity( validateSendCouponItemReqVos.getQuantity() );

        return batchSoaGiveOutCouponItem;
    }
}

忽略属性

@Mapping(target = "couponReceiveChannel",ignore = true)
    public BatchSoaGiveOutCouponRequestVo.BatchSoaGiveOutCouponItem validateSendCouponItemReqVoToBatchSoaGiveOutCouponItem(ValidateSendCouponReqVo.ValidateSendCouponItemReqVo validateSendCouponItemReqVos);

转换后

 @Override
    public BatchSoaGiveOutCouponItem validateSendCouponItemReqVoToBatchSoaGiveOutCouponItem(ValidateSendCouponItemReqVo validateSendCouponItemReqVos) {
        if ( validateSendCouponItemReqVos == null ) {
            return null;
        }

        BatchSoaGiveOutCouponItem batchSoaGiveOutCouponItem = new BatchSoaGiveOutCouponItem();

        batchSoaGiveOutCouponItem.setUserId( validateSendCouponItemReqVos.getUserId() );
        batchSoaGiveOutCouponItem.setUserMobile( validateSendCouponItemReqVos.getUserMobile() );
        batchSoaGiveOutCouponItem.setCouponId( validateSendCouponItemReqVos.getCouponId() );
        batchSoaGiveOutCouponItem.setMemberId( validateSendCouponItemReqVos.getMemberId() );
        batchSoaGiveOutCouponItem.setQuantity( validateSendCouponItemReqVos.getQuantity() );

        return batchSoaGiveOutCouponItem;
    }

一个对象set到另外一个对象

 public MaotaiBookingPo setMaotaiBookingPo(@MappingTarget MaotaiBookingPo maotaiBookingPo, AppointmentReqDto appointmentReqDto);
自动生成后: @Override
public MaotaiBookingPo setMaotaiBookingPo(MaotaiBookingPo maotaiBookingPo, AppointmentReqDto appointmentReqDto) { if ( appointmentReqDto == null ) { return null; } maotaiBookingPo.setId( appointmentReqDto.getId() ); maotaiBookingPo.setUserId( appointmentReqDto.getUserId() ); maotaiBookingPo.setMobile( appointmentReqDto.getMobile() ); maotaiBookingPo.setName( appointmentReqDto.getName() ); maotaiBookingPo.setIdCard( appointmentReqDto.getIdCard() ); maotaiBookingPo.setReceiveAddr( appointmentReqDto.getReceiveAddr() ); maotaiBookingPo.setLon( appointmentReqDto.getLon() ); maotaiBookingPo.setLat( appointmentReqDto.getLat() ); maotaiBookingPo.setProvinceId( appointmentReqDto.getProvinceId() ); maotaiBookingPo.setProvinceName( appointmentReqDto.getProvinceName() ); maotaiBookingPo.setCityId( appointmentReqDto.getCityId() ); maotaiBookingPo.setCityName( appointmentReqDto.getCityName() ); maotaiBookingPo.setDistrictId( appointmentReqDto.getDistrictId() ); maotaiBookingPo.setDistrictName( appointmentReqDto.getDistrictName() ); maotaiBookingPo.setActivityId( appointmentReqDto.getActivityId() ); return maotaiBookingPo; }

常见问题

与lombok冲突解决

clean install就可以看到对应的实现类

<build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.7.0</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.mapstruct</groupId>
                            <artifactId>mapstruct-processor</artifactId>
                            <version>${org.mapstruct.version}</version>
                        </path>
                        <path>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                            <version>${lombok.version}</version>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>

        </plugins>
    </build>

属性相同不自动生成映射

生成了Impl但是属性相同的没有自动生成set方法,手动添加get set方法不使用lombok就没有问题

个人解决方式:

1.尝试升级了lombok版本  我是从从1.14.8 提高到1.18.2就行了

2.保证没有依赖lombok冲突 比如当前项目引入了lombok 其他项目又引入了 版本不一致

 或者是:mapstruct:1.3.0.Final,对应lombok:1.18.10 就可以正常使用了!

启动报错

java: Internal error in the mapping processor: java.lang.NullPointerException: Cannot invoke "java.net.URL.toExternalForm()" because "resource" is null      at org.mapstruct.ap.internal.processor.DefaultVersionInformation.createManifestUrl(DefaultVersionInformation.java:182)      at org.mapstruct.ap.internal.processor.DefaultVersionInformation.openManifest(DefaultVersionInformation.java:153)      at org.mapstruct.ap.internal.processor.DefaultVersionInformation.getLibraryName(DefaultVersionInformation.java:129)      at org.mapstruct.ap.internal.processor.DefaultVersionInformation.getCompiler(DefaultVersionInformation.java:122)      at org.mapstruct.ap.internal.processor.DefaultVersionInformation.fromProcessingEnvironment(DefaultVersionInformation.java:95)      at org.mapstruct.ap.internal.processor.DefaultModelElementProcessorContext.<init>(DefaultModelElementProcessorContext.java:50)      at org.mapstruct.ap.MappingProcessor.processMapperElements(MappingProcessor.java:218)      at org.mapstruct.ap.MappingProcessor.process(MappingProcessor.java:156)      at org.jetbrains.jps.javac.APIWrappers$ProcessorWrapper.process(APIWrappers.java:206)      at jdk.internal.reflect.GeneratedMethodAccessor12.invoke(Unknown Source)      at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)      at java.base/java.lang.reflect.Method.invoke(Method.java:568)      at org.jetbrains.jps.javac.APIWrappers$1.invoke(APIWrappers.java:362)      at jdk.proxy2/org.springframework.boot.configurationprocessor.ConfigurationMetadataAnnotationProcessor.process(Unknown Source)      at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:1023)      at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:939)      at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1267)      at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1382)      at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1234)      at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:916)      at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.lambda$doCall$0(JavacTaskImpl.java:104)      at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.invocationHelper(JavacTaskImpl.java:152)      at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:100)      at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:94)      at org.jetbrains.jps.javac.JavacMain.compile(JavacMain.java:239)      at org.jetbrains.jps.incremental.java.JavaBuilder.lambda$compileJava$2(JavaBuilder.java:519)      at org.jetbrains.jps.incremental.java.JavaBuilder.invokeJavac(JavaBuilder.java:582)      at org.jetbrains.jps.incremental.java.JavaBuilder.compileJava(JavaBuilder.java:517)      at org.jetbrains.jps.incremental.java.JavaBuilder.compile(JavaBuilder.java:361)      at org.jetbrains.jps.incremental.java.JavaBuilder.doBuild(JavaBuilder.java:286)      at org.jetbrains.jps.incremental.java.JavaBuilder.build(JavaBuilder.java:240)      at org.jetbrains.jps.incremental.IncProjectBuilder.runModuleLevelBuilders(IncProjectBuilder.java:1556)      at org.jetbrains.jps.incremental.IncProjectBuilder.runBuildersForChunk(IncProjectBuilder.java:1185)      at org.jetbrains.jps.incremental.IncProjectBuilder.buildTargetsChunk(IncProjectBuilder.java:1336)      at org.jetbrains.jps.incremental.IncProjectBuilder.buildChunkIfAffected(IncProjectBuilder.java:1150)      at org.jetbrains.jps.incremental.IncProjectBuilder.buildChunks(IncProjectBuilder.java:918)      at org.jetbrains.jps.incremental.IncProjectBuilder.runBuild(IncProjectBuilder.java:474)      at org.jetbrains.jps.incremental.IncProjectBuilder.build(IncProjectBuilder.java:197)      at org.jetbrains.jps.cmdline.BuildRunner.runBuild(BuildRunner.java:150)      at org.jetbrains.jps.cmdline.BuildSession.runBuild(BuildSession.java:387)      at org.jetbrains.jps.cmdline.BuildSession.run(BuildSession.java:212)      at org.jetbrains.jps.cmdline.BuildMain$MyMessageHandler.lambda$channelRead0$0(BuildMain.java:211)      at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)      at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)      at java.base/java.lang.Thread.run(Thread.java:833)  

idea增加配置

-Djps.track.ap.dependencies=false

打包报错

maven install cannot access class com.sun.tools.javac.processing.JavacProcessingEnvironment 

检查jdk版本

 

posted @ 2020-04-23 18:02  意犹未尽  阅读(1365)  评论(0编辑  收藏  举报