属性拷贝MapStruct

端请求通过VO对象接收,并通过DTO对象进行流转,最后转换成DO对象与数据库DAO层进行交互,反之亦然。

当业务简单的时候,可以通过手动编码getter/setter函数来复制对象属性。但是当业务变的复杂,对象属性变得很多,那么手写复制属性代码不仅十分繁琐,非常耗时间,并且还可能容易出错。

为了解决这个痛点,在项目初期,项目的解决方法是随手写的转换工具函数:根据变量名进行反射,对基础类型和枚举的变量进行赋值。

总结下目前该工具函数的优缺点:

优点:

  1. 开发效率高,随时想要转换的时候,传入源对象以及指定class,调用下函数即可。

缺点:

  1. 项目中大量的反射会严重影响代码执行效率
  2. 由于使用了反射,所以成员变量的使用被追踪就很麻烦
  3. 转换失败只有在运行中报错才会发现
  4. 对于嵌套对象字段的情况无能为力
  5. 只能对基础类型进行复制
  6. 对字段名不一致的属性无法赋值

接下来就要介绍MapStruct 这个工具类,这个工具类之所以运行速度与硬编码差不多,这是因为MapStruct在编译期间就生成属性复制的代码,运行期间就无需使用反射或者字节码技术,从而确保了高性能。

另外,由于编译期间就生成了代码,所以如果有任何问题,编译期间就可以提前暴露,这对于开发人员来讲就可以提前解决问题,而不用等到代码应用上线了,运行之后才发现错误。

所以,为了克服项目中当前函数的被提到的五个缺点,笔者引入了MapStruct。

2. 如何引入MapStruct

只需要引入MapStruct的依赖,同时由于MapStruct需要在编译器期间生成代码,所以我们需要maven-compiler-plugin插件中配置

复制

// pom.xml
        <dependency>
            <groupId>org.MapStruct</groupId>
            <artifactId>MapStruct</artifactId>
            <version>1.4.1.Final</version>
        </dependency>

.高效性:

1.编译期   自动生成映射代码          

类型检查报错

2.灵活性:支持复杂映射(对象、集合列表)  

   支持属性不同字段名、类型的赋值

3.直观性:使用注解来定义映射规则     (根据需求指定返回类型、忽略属性,添加        条件判断来决定是否执行映射操作) 

 

package com.mdgyl.hussar.basic.supplier.changeorder.converter.struct;


import com.mdgyl.common.util.DateUtils;
import com.mdgyl.hussar.basic.model.supplier.masterdata.*;
import com.mdgyl.hussar.basic.model.supplier.supplierchangeorder.*;
import com.mdgyl.hussar.basic.supplier.changeorder.domain.*;
import org.apache.commons.lang3.StringUtils;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;

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

    @Mappings({
            @Mapping(target = "score", expression = "java(exchangeRateDO.getScore() == null? null:exchangeRateDO.getScore().toString())"),
            @Mapping(target = "operatingStartTime", expression = "java(exchangeRateDO.getOperatingStartTime() == null? null:formatDate(exchangeRateDO.getOperatingStartTime()))"),
    })
    SupplierChangeOrderModel doToModel(SupplierChangeOrderDo exchangeRateDO);

    @Mappings({
            @Mapping(target = "id", ignore = true),
            @Mapping(source = "tenantId", target = "tenantId"),
            @Mapping(target = "status", ignore = true),
            @Mapping(source = "id", target = "supplierDataId"),
            @Mapping(target = "deleteFlag", constant = "0")
    })
    SupplierChangeOrderModel converterSupplierToChangeOrder(SupplierModel supplierModel);

    @Mappings({
            @Mapping(target = "id", ignore = true),
            @Mapping(source = "id", target = "supplierAddressId")
    })
    SupplierChangeOrderAddressModel convertAddressesModel(SupplierAddressModel supplierAddressModel);

    @Mappings({
            @Mapping(target = "id", ignore = true),
            @Mapping(source = "id", target = "supplierBankId")
    })
    SupplierChangeOrderBankModel convertBankModel(SupplierBankModel supplierBankModel);

    @Mappings({
            @Mapping(target = "id", ignore = true),
            @Mapping(source = "id", target = "supplierContactsId"),
    })
    SupplierChangeOrderContactsModel convertContactModel(SupplierContactsModel supplierContactsModel);

    @Mappings({
            @Mapping(target = "id", ignore = true),
            @Mapping(source = "id", target = "supplierInfoId"),
    })
    SupplierChangeOrderInfoModel convertOderInfoModel(SupplierInfoModel supplierInfo);

    @Mappings({
            @Mapping(target = "score", expression = "java(parseBigDecimal(supplierChangeOrderModel.getScore()))"),
            @Mapping(target = "operatingStartTime", expression = "java(supplierChangeOrderModel.getOperatingStartTime() == null ? null : parseDate(supplierChangeOrderModel.getOperatingStartTime()))"),
    })
    SupplierChangeOrderDo converterModelToDo(SupplierChangeOrderModel supplierChangeOrderModel);

    @Mappings({
            @Mapping(target = "taxRate", expression = "java(parseBigDecimal(supplierChangeOrderModel.getTaxRate()))"),
            @Mapping(target = "staffSize", expression = "java(supplierChangeOrderModel.getStaffSize() == null || supplierChangeOrderModel.getStaffSize().isEmpty() ? null : new Integer(supplierChangeOrderModel.getStaffSize()))"),
            @Mapping(target = "numberOfInsured", expression = "java(supplierChangeOrderModel.getNumberOfInsured() == null || supplierChangeOrderModel.getNumberOfInsured().isEmpty() ? null : new Integer(supplierChangeOrderModel.getNumberOfInsured()))")
    })
    SupplierChangeOrderInfo converterInfoModelToDo(SupplierChangeOrderInfoModel supplierChangeOrderModel);

    SupplierChangeOrderAddress converterAddressModelToDo(SupplierChangeOrderAddressModel supplierChangeOrderAddressModel);

    SupplierChangeOrderBank converterBankModelToDo(SupplierChangeOrderBankModel supplierChangeOrderBankModel);

    SupplierChangeOrderContacts converterContactsModel(SupplierChangeOrderContactsModel supplierChangeOrderContactsModel);

    @Mappings({
            @Mapping(target = "taxRate", expression = "java(supplierInfo.getTaxRate() == null? null:supplierInfo.getTaxRate().toString())"),
            @Mapping(target = "staffSize", expression = "java(supplierInfo.getStaffSize() == null? null:supplierInfo.getStaffSize().toString())"),
            @Mapping(target = "numberOfInsured", expression = "java(supplierInfo.getNumberOfInsured() == null? null:supplierInfo.getNumberOfInsured().toString())")
    })
    SupplierChangeOrderInfoModel converterInfoDoToModel(SupplierChangeOrderInfo supplierInfo);

    SupplierChangeOrderAddressModel convertAddressesDoToModel(SupplierChangeOrderAddress supplierChangeOrderAddress);

    SupplierChangeOrderContactsModel convertContactsDoToModel(SupplierChangeOrderContacts supplierChangeOrderContacts);

    SupplierChangeOrderBankModel convertBankDoToModel(SupplierChangeOrderBank supplierChangeOrderContacts);

    @Mappings({
            @Mapping(source = "supplierDataId", target = "id"),
            @Mapping(source = "status", target = "status", ignore = true),
            @Mapping(target = "score", expression = "java(parseBigDecimal(changeOrderModel.getScore()))"),
            @Mapping(target = "operatingStartTime", expression = "java(parseLocalDateTime(changeOrderModel.getOperatingStartTime()))")
    })
    SupplierModel converterChangeOrderToSupplier(SupplierChangeOrderModel changeOrderModel);

    @Mappings({
            @Mapping(source = "supplierInfoId", target = "id"),
            @Mapping(target = "staffSize", expression = "java(changeOrderInfo.getStaffSize() == null|| changeOrderInfo.getStaffSize().isEmpty() ? null : Integer.parseInt(changeOrderInfo.getStaffSize()))"),
            @Mapping(target = "taxRate", expression = "java(parseBigDecimal(changeOrderInfo.getTaxRate()))"),
            @Mapping(target = "numberOfInsured", expression = "java(changeOrderInfo.getNumberOfInsured() == null || changeOrderInfo.getNumberOfInsured().isEmpty()? null : Integer.parseInt(changeOrderInfo.getNumberOfInsured()))"),

    })
    SupplierInfoModel convertOderInfoToSupplierModel(SupplierChangeOrderInfoModel changeOrderInfo);

    @Mappings({
            @Mapping(source = "supplierAddressId", target = "id")
    })
    SupplierAddressModel convertAddressesToSupplierModel(SupplierChangeOrderAddressModel supplierChangeOrderAddressModel);

    @Mappings({
            @Mapping(source = "supplierBankId", target = "id")
    })
    SupplierBankModel convertBankToSupplierModel(SupplierChangeOrderBankModel supplierBankModel);

    @Mappings({

            @Mapping(source = "supplierContactsId", target = "id"),
    })
    SupplierContactsModel convertContactToSupplierModel(SupplierChangeOrderContactsModel supplierContactsModel);

    default Date parseDate(String dateString) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        try {
            return format.parse(dateString);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    default BigDecimal parseBigDecimal(String taxRate) {
        if (StringUtils.isEmpty(taxRate)) {
            return null;
        }
        return new BigDecimal(taxRate);
    }

    default String formatDate(Date date) {
        SimpleDateFormat format = new SimpleDateFormat(DateUtils.YYYY_MM_DD);
        return format.format(date);
    }

    // 自定义方法用于解析日期字符串
    default LocalDate parseLocalDate(String dateString) {
        if (dateString == null) {
            return null;
        }
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DateUtils.YYYY_MM_DD);
        try {
            LocalDateTime dateTime = LocalDateTime.parse(dateString, formatter);
            return dateTime.toLocalDate();
        } catch (Exception e) {
            return null;
        }
    }

    // 自定义方法用于解析日期字符串
    default LocalDateTime parseLocalDateTime(String dateStr) {
        if (StringUtils.isBlank(dateStr)) {
            return null;
        }

        try {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DateUtils.YYYY_MM_DD_HH_MM_SS);
            return LocalDateTime.parse(dateStr, formatter);
        } catch (Exception e) {
            return null;
        }
    }
}

package com.mdgyl.hussar.basic.supplier.changeorder.converter.service;

import com.google.common.collect.Lists;
import com.jxdinfo.hussar.support.audit.plugin.mongodb.support.query.entity.Page;
import com.mdgyl.common.helper.CollectionHelper;
import com.mdgyl.common.helper.MapHelper;
import com.mdgyl.hussar.basic.enums.SupplierChangeOrderStatusEnum;
import com.mdgyl.hussar.basic.enums.SupplierStatusEnum;
import com.mdgyl.hussar.basic.model.supplier.masterdata.SupplierAddressModel;
import com.mdgyl.hussar.basic.model.supplier.masterdata.SupplierBankModel;
import com.mdgyl.hussar.basic.model.supplier.masterdata.SupplierContactsModel;
import com.mdgyl.hussar.basic.model.supplier.masterdata.SupplierModel;
import com.mdgyl.hussar.basic.model.supplier.supplierchangeorder.*;
import com.mdgyl.hussar.basic.supplier.changeorder.converter.struct.ChangeOrderMapperConverter;
import com.mdgyl.hussar.basic.supplier.changeorder.domain.*;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class ChangeOrderServiceConverter {

    public static SupplierChangeOrderModel converterModel(SupplierChangeOrderDo supplierChangeOrderDo) {
        if (supplierChangeOrderDo == null) {
            return null;
        }
        SupplierChangeOrderModel supplierChangeOrderModel = ChangeOrderMapperConverter.INSTANCE.doToModel(supplierChangeOrderDo);
        supplierChangeOrderModel.setStatus(SupplierChangeOrderStatusEnum.getDescByCode(supplierChangeOrderDo.getStatus()));
        return supplierChangeOrderModel;
    }


    public static Page<SupplierChangeOrderModel> converterModelPage(Page<SupplierChangeOrderDo> supplierChangeOrderDos) {
        if (supplierChangeOrderDos == null) {
            return new Page<SupplierChangeOrderModel>(); // 如果输入是 null,返回一个空的 Page
        }

        // 转换数据列表
        List<SupplierChangeOrderModel> modelList = supplierChangeOrderDos.getRecords().stream()
                .map(ChangeOrderServiceConverter::converterModel)
                .collect(Collectors.toList());


        // 创建并返回新的 Page<SupplierChangeOrderModel> 对象
        Page<SupplierChangeOrderModel> page = new Page<>(supplierChangeOrderDos.getCurrent(), supplierChangeOrderDos.getSize(), supplierChangeOrderDos.getTotal());
        page.setRecords(modelList);
        return page;
    }

    public static SupplierChangeOrderModel converterSupplierToChangeOrderModel(SupplierModel supplierModel) {
        if (supplierModel == null) {
            return null;
        }
        SupplierChangeOrderModel supplierChangeOrderModel = ChangeOrderMapperConverter.INSTANCE.converterSupplierToChangeOrder(supplierModel);
        SupplierStatusEnum supplierStatus = supplierModel.getStatus();
        supplierChangeOrderModel.setAddresses(CollectionHelper.collectNotNullList(supplierModel.getAddresses(), ChangeOrderMapperConverter.INSTANCE::convertAddressesModel));
        supplierChangeOrderModel.setBanks(CollectionHelper.collectNotNullList(supplierModel.getBanks(), ChangeOrderMapperConverter.INSTANCE::convertBankModel));
        supplierChangeOrderModel.setContacts(CollectionHelper.collectNotNullList(supplierModel.getContacts(), ChangeOrderMapperConverter.INSTANCE::convertContactModel));
        SupplierChangeOrderInfoModel supplierChangeOrderInfoModel = ChangeOrderMapperConverter.INSTANCE.convertOderInfoModel(supplierModel.getSupplierInfo());
        if (ObjectUtils.isEmpty(supplierChangeOrderInfoModel)) {
            supplierChangeOrderInfoModel=new SupplierChangeOrderInfoModel();
            supplierChangeOrderInfoModel.setSupplierDataId(supplierModel.getId());
        }
        supplierChangeOrderInfoModel.setSupplierStatus(supplierStatus);
        supplierChangeOrderModel.setChangeOrderInfo(supplierChangeOrderInfoModel);
        return supplierChangeOrderModel;
    }

    public static SupplierChangeOrderModel converterToChangeOrderModel(SupplierChangeOrderDo supplierChangeOrder, SupplierChangeOrderInfo changeOrderInfoDo, List<SupplierChangeOrderAddress> addresses, List<SupplierChangeOrderBank> banks, List<SupplierChangeOrderContacts> contacts) {
        if (supplierChangeOrder == null) {
            return null;
        }
        SupplierChangeOrderModel supplierChangeOrderModel = ChangeOrderMapperConverter.INSTANCE.doToModel(supplierChangeOrder);
        supplierChangeOrderModel.setAddresses(CollectionHelper.collectNotNullList(addresses, ChangeOrderMapperConverter.INSTANCE::convertAddressesDoToModel));
        supplierChangeOrderModel.setBanks(CollectionHelper.collectNotNullList(banks, ChangeOrderMapperConverter.INSTANCE::convertBankDoToModel));
        supplierChangeOrderModel.setContacts(CollectionHelper.collectNotNullList(contacts, ChangeOrderMapperConverter.INSTANCE::convertContactsDoToModel));
        supplierChangeOrderModel.setChangeOrderInfo(ChangeOrderMapperConverter.INSTANCE.converterInfoDoToModel(changeOrderInfoDo));
        return supplierChangeOrderModel;
    }


    public static SupplierChangeOrderDo converterModelToDo(SupplierChangeOrderModel supplierChangeOrderModel) {
        if (supplierChangeOrderModel == null) {
            return null;
        }
        return ChangeOrderMapperConverter.INSTANCE.converterModelToDo(supplierChangeOrderModel);
    }

    public static SupplierChangeOrderInfo converterInfoModelToDo(SupplierChangeOrderInfoModel supplierChangeOrderInfoModel) {
        if (supplierChangeOrderInfoModel == null) {
            return null;
        }
        return ChangeOrderMapperConverter.INSTANCE.converterInfoModelToDo(supplierChangeOrderInfoModel);
    }


    public static List<SupplierChangeOrderAddress> converterAddressModelToDoList(List<SupplierChangeOrderAddressModel> supplierChangeOrderAddressList) {
        if (CollectionUtils.isEmpty(supplierChangeOrderAddressList)) {
            return Lists.newArrayList();
        }
        return supplierChangeOrderAddressList.stream().map(ChangeOrderMapperConverter.INSTANCE::converterAddressModelToDo).collect(Collectors.toList());
    }

    public static List<SupplierChangeOrderBank> converterBankModelToDoList(List<SupplierChangeOrderBankModel> supplierChangeOrderBankList) {
        if (CollectionUtils.isEmpty(supplierChangeOrderBankList)) {
            return Lists.newArrayList();
        }
        return supplierChangeOrderBankList.stream().map(ChangeOrderMapperConverter.INSTANCE::converterBankModelToDo).collect(Collectors.toList());
    }

    public static List<SupplierChangeOrderContacts> converterContactsModelToDoList(List<SupplierChangeOrderContactsModel> supplierChangeOrderContactList) {
        if (CollectionUtils.isEmpty(supplierChangeOrderContactList)) {
            return Lists.newArrayList();
        }
        return supplierChangeOrderContactList.stream().map(ChangeOrderMapperConverter.INSTANCE::converterContactsModel).collect(Collectors.toList());
    }


    public static List<SupplierChangeOrderAddressModel> converterChangeOrderAddressList(List<SupplierChangeOrderAddress> addressesList) {
        if (CollectionUtils.isEmpty(addressesList)) {
            return Lists.newArrayList();
        }
        return addressesList.stream().map(ChangeOrderMapperConverter.INSTANCE::convertAddressesDoToModel).collect(Collectors.toList());
    }

    public static List<SupplierChangeOrderAddressModel> converterAddressList(List<SupplierAddressModel> addressesList) {
        if (CollectionUtils.isEmpty(addressesList)) {
            return Lists.newArrayList();
        }
        return addressesList.stream().map(ChangeOrderMapperConverter.INSTANCE::convertAddressesModel).collect(Collectors.toList());
    }


    public static List<SupplierChangeOrderBankModel> converterBankList(List<SupplierBankModel> bankList) {
        if (CollectionUtils.isEmpty(bankList)) {
            return Lists.newArrayList();
        }
        return bankList.stream().map(ChangeOrderMapperConverter.INSTANCE::convertBankModel).collect(Collectors.toList());
    }

    public static List<SupplierChangeOrderContactsModel> converterContactsList(List<SupplierContactsModel> bankList) {
        if (CollectionUtils.isEmpty(bankList)) {
            return Lists.newArrayList();
        }
        return bankList.stream().map(ChangeOrderMapperConverter.INSTANCE::convertContactModel).collect(Collectors.toList());
    }

    public static SupplierChangeOrderInfoModel converterInfoModel(SupplierChangeOrderInfo supplierInfo) {
        if (supplierInfo == null) {
            return null;
        }
        return ChangeOrderMapperConverter.INSTANCE.converterInfoDoToModel(supplierInfo);
    }

    public static List<SupplierChangeOrderContactsModel> converterChangeOrdeContactsList(List<SupplierChangeOrderContacts> contactList) {
        if (CollectionUtils.isEmpty(contactList)) {
            return Lists.newArrayList();
        }
        return contactList.stream().map(ChangeOrderMapperConverter.INSTANCE::convertContactsDoToModel).collect(Collectors.toList());
    }

    public static List<SupplierChangeOrderBankModel> converterChangeOrdeBankList(List<SupplierChangeOrderBank> banks) {
        if (CollectionUtils.isEmpty(banks)) {
            return Lists.newArrayList();
        }
        return banks.stream().map(ChangeOrderMapperConverter.INSTANCE::convertBankDoToModel).collect(Collectors.toList());
    }

    public static List<Long> getAddressDeleteIds(List<SupplierChangeOrderAddressModel> supplierAddressModels, Map<Long, SupplierChangeOrderAddressModel> addressUpdateMap) {
        // 对比出删除的现场考察数据
        return CollectionHelper.collectNotNullList(supplierAddressModels, param -> {
            Long addressId = param.getId();
            SupplierChangeOrderAddressModel supplierChangeOrderAddressModel = MapHelper.getValue(addressUpdateMap, addressId);
            if (supplierChangeOrderAddressModel == null) {
                return addressId;
            }
            return null;
        });
    }

    public static List<Long> getBankDeleteIds(List<SupplierChangeOrderBankModel> supplierBankModels, Map<Long, SupplierChangeOrderBankModel> bankUpdateMap) {

        // 对比出删除的样品检测数据
        return CollectionHelper.collectNotNullList(supplierBankModels, param -> {
            Long bankId = param.getId();
            SupplierChangeOrderBankModel supplierChangeOrderBankModel = MapHelper.getValue(bankUpdateMap, bankId);
            if (supplierChangeOrderBankModel == null) {
                return bankId;
            }
            return null;
        });
    }

    public static List<Long> getContactsDeleteIds(List<SupplierChangeOrderContactsModel> supplierContactsModels, Map<Long, SupplierChangeOrderContactsModel> contactUpdateMap) {
        // 对比出删除的资质审查数据
        return CollectionHelper.collectNotNullList(supplierContactsModels, param -> {
            Long contactsId = param.getId();
            SupplierChangeOrderContactsModel supplierChangeOrderContactsModel = MapHelper.getValue(contactUpdateMap, contactsId);
            if (supplierChangeOrderContactsModel == null) {
                return contactsId;
            }
            return null;
        });
    }

    public static SupplierModel converterChangeOrderToSupplierModel(SupplierChangeOrderModel changeOrderModel) {
        if (changeOrderModel == null) {
            return null;
        }
        SupplierModel supplierModel = ChangeOrderMapperConverter.INSTANCE.converterChangeOrderToSupplier(changeOrderModel);
        supplierModel.setStatus(changeOrderModel.getChangeOrderInfo().getSupplierStatus());
        supplierModel.setAddresses(CollectionHelper.collectNotNullList(changeOrderModel.getAddresses(), ChangeOrderMapperConverter.INSTANCE::convertAddressesToSupplierModel));
        supplierModel.setBanks(CollectionHelper.collectNotNullList(changeOrderModel.getBanks(), ChangeOrderMapperConverter.INSTANCE::convertBankToSupplierModel));
        supplierModel.setContacts(CollectionHelper.collectNotNullList(changeOrderModel.getContacts(), ChangeOrderMapperConverter.INSTANCE::convertContactToSupplierModel));
        supplierModel.setSupplierInfo(ChangeOrderMapperConverter.INSTANCE.convertOderInfoToSupplierModel(changeOrderModel.getChangeOrderInfo()));
        return supplierModel;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值