在实际的业务开发中,我们经常会碰到BO、PO、DTO等对象属性之间的赋值,当属性较多的时候我们使用get,set的方式进行赋值的工作量相对较大,因此很多人会选择使用spring提供的拷贝工具
BeanUtils
的
copyProperties
方法完成对象之间属性的拷贝。
通过这种方式可以很大程度上降低我们手动编写对象属性赋值代码的工作量,既然它那么方便为什么还不建议使用呢?
我总结为以下几点:
在实际开发中,很可能会出现同一字段在不同的类中定义的类型不一致,例如Id,可能在A类中定义的类型为Long,在B类中定义的类型为String,此时如果使用
BeanUtils.copyProperties
进行拷贝,就会出现拷贝失败的现象,导致对应的字段为null
如果同一个字段分别使用包装类和基本类型,在没有传递实际值的时候,会出现异常
注意,如果一个布尔类型的属性分别使用了基本类型和包装类型,且属性名如果使用is开头,例如isSuccess,也会导致拷贝失败
在业务开发时,我们可能会有部分字段拷贝的需求,被拷贝的数据里面如果某些字段有null值存在,但是对应的需要被拷贝过去的数据的相同字段的值并不为null,如果直接使用
BeanUtils.copyProperties
进行数据拷贝,就会出现被拷贝数据的null值覆盖拷贝目标数据的字段,导致原有的数据失效
简单举个例子,我有一个BO(已经存在了A属性且有值),需要拷贝DTO中除了A属性的其他属性(DTO中的A属性为null),此时使用
BeanUtils.copyProperties
就会导致BO中的A属性的值被DTO中A的null给覆盖了
虽然可以使用
BeanUtils.copyProperties
的重载方法,配合自定义的
ConvertUtilsBean
来实现部分字段的拷贝,但是这么做本身也比较复杂,也就失去了使用
BeanUtils.copyProperties
拷贝数据的意义,因此也不推荐这么做。
为什么使用
MapperStruct
? ---> 快,对就是因为很快,性能比
BeanUtils.copyProperties
快很多很多
放张参考图给大家参考
那么为什么
MapperStruct比BeanUtils.copyProperties
快?
-
-
预编译的高效代码执行更快 (看到这里就懵了,预编译?咋回事啊到底)
什么是预编译? --- 在项目启动的时候,自动帮你生成对象拷贝的代码,拒绝使用的时候才去通过反射调用get/set...
具体的可以往下看
@Generated(
value = "org.mapstruct.ap.MappingProcessor",
date = "2024-02-07T00:50:05+0800",
comments = "version: 1.4.2.Final, compiler: javac, environment: Java 1.8.0_211 (Oracle Corporation)"
)
public class XXXDTOConverterImpl implements XXXDTOConverter {
@Override
public XXXBO convertDtoToBo(XXXDTO XXXDTO) {
if ( XXXDTO == null ) {
return null;
}
XXXBO XXXBO = new XXXBO();
XXXBO.setId( XXXDTO.getId() );
XXXBO.setLabelName( XXXDTO.getLabelName() );
XXXBO.setSortNum( XXXDTO.getSortNum() );
XXXBO.setCategoryId( XXXDTO.getCategoryId() );
return XXXBO;
}
}
基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能
-
项目地址:https://github.com/YunaiV/ruoyi-vue-pro
-
视频教程:https://doc.iocoder.cn/video/
Maven引入依赖
<dependency>
<groupId>org.mapstructgroupId>
<artifactId>mapstructartifactId>
<version>1.4.2.Finalversion>
dependency>
<dependency>
<groupId>org.mapstructgroupId>
<artifactId>mapstruct-processorartifactId>
<version>1.4.2.Finalversion>
dependency>
编写代码
@Data
public class SubjectLabelDTO implements Serializable {
private String labelName;
}
@Data
public class SubjectLabelBO implements Serializable {
private String labelName;
}
@Mapper
public interface SubjectLabelDTOConverter {
SubjectLabelDTOConverter INSTANCE = Mappers.getMapper(SubjectLabelDTOConverter.class);
SubjectLabelBO convertDtoToBo(SubjectLabelDTO subjectLabelDTO);
}
public Result add( SubjectLabelDTO subjectLabelDTO){
SubjectLabelBO subjectLabelBO = SubjectLabelDTOConverter.INSTANCE
.convertDtoToBo(subjectLabelDTO);
}
基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能
-
项目地址:https://github.com/YunaiV/yudao-cloud
-
视频教程:https://doc.iocoder.cn/video/