MapStruct实体映射工具

一丶MapStruct是什么

MapStruct 是一个代码生成器,它基于配置方法的约定,极大地简化了 Java Bean 类型之间映射的实现,生成的映射代码使用普通方法调用,因此快速、类型安全且易于理解。

官方网站 MapStruct – Java bean mappings, the easy way!

二丶为什么需要MapStruct

多层应用程序通常需要在不同的对象模型(例如实体和 DTO)之间进行映射。编写这样的映射代码是一项繁琐且容易出错的任务。MapStruct旨在通过尽可能自动化来简化这项工作。

与其他映射框架相比,MapStruct在编译时生成bean映射,这确保了高性能,允许快速的开发人员反馈和彻底的错误检查。

方案

优点

缺点

手写代码 1. 灵活性高
2. 方便后续重构
1. 重复性工作多
2. 手写代码容易遗漏掉有些字段
BeanUtils.copyProperties 1. 使用简单
2. Apache 的包效率比较低,spring 的包效率可以接受
1. 复杂场景支持不足,控制 copy 粒度太粗
2. 不易重构
MapStruct 1. 灵活性高支持简单,复杂,嵌套,自定义扩展等多种手段
2. 编译期生成,没有效率问题
1.不方便后续重构

三丶MapStruct 性能优于BeanUtils的原因

Java程序执行的过程,是由编译器先把java文件编译成class字节码文件,然后由JVM去解释执行class文件。Mapstruct正是在java文件到class这一步帮我们实现了转换方法,即做了预处理,提前编译好文件(Java动态编译),通过查看class文件,

可以看出CarMapper被打上org.mapstruct.Mapper注解后,编译器自动会帮我们生成一个实现类CarMapperImpl,并实现了carToCarDto这个方法,看下面的代码块,从生成的代码看,生成的代码只使用了CarDO get方法和CarDTO set方法,没有其他复杂逻辑。

MapStruct实现

编译后会在target文件夹下生成实现类CarMapperImpl

CarMapper代码

package com.tuhu.cas.service.convert;
 
import com.tuhu.cas.dto.CarDTO;
import com.tuhu.cas.mysql.cas.write.dataobject.CarDO;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
 
@Mapper
public interface CarMapper {
 
    CarMapper INSTANCE = Mappers.getMapper(CarMapper.class);
 
    @Mapping(target = "manufacturer", source = "make")
    @Mapping(target = "seatCount", source = "numberOfSeats")
    CarDTO carToCarDto(CarDO car);
 
}

CarMapperImpl代码

package com.tuhu.cas.service.convert;
 
import com.tuhu.cas.dto.CarDTO;
import com.tuhu.cas.mysql.cas.write.dataobject.CarDO;
import javax.annotation.Generated;
 
@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2022-11-22T19:44:12+0800",
    comments = "version: 1.3.1.Final, compiler: javac, environment: Java 1.8.0_111 (Oracle Corporation)"
)
public class CarMapperImpl implements CarMapper {
 
    @Override
    public CarDTO carToCarDto(CarDO car) {
        if ( car == null ) {
            return null;
        }
 
        CarDTO carDTO = new CarDTO();
 
        carDTO.setSeatCount( car.getNumberOfSeats() );
        carDTO.setManufacturer( car.getMake() );
 
        return carDTO;
    }
}

Spring的BeanUtils.copyProperties源码

通过源码,我们可以看到有很多的遍历,去获取属性,获取方法,设置方法可访问,通过反射,所以执行效率相对Mapstruct来说,是比较低的。回头看Mapstruct自动生成的实现类,简洁、高效。

/**
 * Copy the property values of the given source bean into the given target bean.
 * <p>Note: The source and target classes do not have to match or even be derived
 * from each other, as long as the properties match. Any bean properties that the
 * source bean exposes but the target bean does not will silently be ignored.
 * @param source the source bean
 * @param target the target bean
 * @param editable the class (or interface) to restrict property setting to
 * @param ignoreProperties array of property names to ignore
 * @throws BeansException if the copying failed
 * @see BeanWrapper
 */
private static void copyProperties(Object source, Object target, @Nullable Class<?> editable,
        @Nullable String... ignoreProperties) throws BeansException {
 
    Assert.notNull(source, "Source must not be null");
    Assert.notNull(target, "Target must not be null");
 
    Class<?> actualEditable = target.getClass(

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值