欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 旅游 > 告别BeanUtils!MapStruct Plus快速入门与最佳实践

告别BeanUtils!MapStruct Plus快速入门与最佳实践

2025/4/10 9:17:56 来源:https://blog.csdn.net/weixin_45481821/article/details/147031475  浏览:    关键词:告别BeanUtils!MapStruct Plus快速入门与最佳实践

文章目录

前言

一、安装

二、单个对象转换

1.指定对象映射关系

2.编写测试代码

3.运行结果

4.原理解析 

三、自定义实体类属性转换 

1.自定义一个类型转换器

2.使用类型转换器

3.运行结果

四、工具类

总结

前言

在开发中,我们有VO、BO、POJO常见对象类型,分别服务于不同层次和常见,不同的对象类型

需要做转换,传统的方式我们使用set/get,但是一个一个手动写太繁琐和太麻烦,所以像

apache、Spring、hutool都提供了BeaenUtils工具类,那我们为什么还要使用MapStruct Plus

呢???主要是BeanUtils底层用的是反射,性能较差,而MapStruct Plus是编译期生成的,接近原

生代码效率,你就理解MapStruct Plus性能 > BeanUtils 比它厉害 牛逼就好了。MapStruct Plus是

MapStruct的PLUS版本,兼容MapStruct,额.....没学过MapStruc,不影响。

一、安装

注意:这里跟官网有点不一样,我们使用lombok,在 Maven 配置中引入 mapstruct-plus-

processor 和 lombok-mapstruct-binding 依赖是为了解决 ​编译期代码生成协同问题​​ 和 ​​Lombok

与 MapStruct 的兼容性问题​​。

Lombok 和 MapStruct 均依赖编译期注解处理器生成代码。若 Lombok 未先生成 getter/setter 方

法,MapStruct 将无法识别字段导致编译失败。lombok-mapstruct-binding 协调两者的处理顺序,

确保 Lombok 优先执行

从 Lombok 1.18.16 开始,必须引入该绑定库,否则 MapStruct 无法识别 Lombok 生成的构造器或

Builder 模式(如 @Builder 注解生成的类)。

<properties><mapstruct-plus.version>最新版本</mapstruct-plus.version>
</properties>
<dependencies><dependency><groupId>io.github.linpeilie</groupId><artifactId>mapstruct-plus-spring-boot-starter</artifactId><version>${mapstruct-plus.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>io.github.linpeilie</groupId><artifactId>mapstruct-plus-processor</artifactId><version>${mapstruct-plus.version}</version></path><path><groupId>org.projectlombok</groupId><artifactId>lombok-mapstruct-binding</artifactId><version>${mapstruct-plus.lombok.version}</version></path></annotationProcessorPaths></configuration></plugin></plugins>
</build>

二、单个对象转换

1.指定对象映射关系

在 User 或者 UserVo 上面增加注解 —— @AutoMapper,并设置 target 为对方类。
以下面代码举例,添加注解:@AutoMapper(target = UserVo.class)

User类:

@Data
@AutoMapper(target = UserVo.class)
public class User {private String username;private int age;private String password;
}

UserVo类:

@Data
@AutoMapper(target = User.class)
public class UserVo {private String username;private int age;private String password;
}

2.编写测试代码

@SpringBootTest
public class QuickStartTest {@Autowiredprivate Converter converter;@Testpublic void test(){// 创建 User 对象User user = new User();user.setUsername("wen");user.setAge(18);user.setPassword("123456");// 使用 MapStruct plus 进行对象间转换:User =》 UserVoUserVo userVo = converter.convert(user, UserVo.class);// 输出转换之后的对象System.out.println(userVo);// 测试System.out.println("user.getUsername().equals(userVo.getUsername()) = " + user.getUsername().equals(userVo.getUsername()));System.out.println("user.getAge() == userVo.getAge() = " + user.getAge() +"---" + userVo.getAge());}
}

3.运行结果

4.原理解析 

User转为UserVo主要是UserVo userVo = converter.convert(user,UserVo.class);底层其实set/get实现。

  @Overridepublic UserVo convert(User source) {if ( source == null ) {return null;}UserVo userVo = new UserVo();userVo.setTagList( stringToListConverter.stringToList( source.getTags() ) );userVo.setUsername( source.getUsername() );userVo.setAge( source.getAge() );return userVo;}

在target目录下的generated-source/annotations/com.taoran.mapstructplus.entity

三、自定义实体类属性转换 

想起手上有一个需求,前端传身份正反面图片URL,传的是List<String>,但是数据库保存是String

并且使用,相隔保存到收据库,可以使用MapStruct Plus的自定义实体类属性转换。

有两种方式,我们讲第二种。

1、@AutoMapping expression指定表达式:适合简单。

2、自定义一个类型转换器:适合复杂。

1.自定义一个类型转换器

String转List转换器

@Component
public class StringToListConverter {public List<String> stringToList(String str) {if (str == null) {return Collections.emptyList();}return Arrays.asList(str.split(","));}
}

List转String转换器

@Component
public class ListToStringConverter {public String listToString(List<String> list) {if (list == null || list.isEmpty()) {return null;}return String.join(",", list);}
}

2.使用类型转换器

@AutoMapper注解中使用uses指定转换器,转换器可以使用多个,并且需要在转换的属性加上

@AutoMapping注解,target指向另一个需要转化的属性。

User:

@Data
@AutoMapper(target = UserVo.class,uses = StringToListConverter.class)
public class User {private String username;private int age;private String password;@AutoMapping(target = "tagList")private String tags;
}

UserVo:

@Data
@AutoMapper(target = User.class,uses = ListToStringConverter.class)
public class UserVo {private String username;private int age;@AutoMapping(target = "tags")private List<String> tagList;
}

测试类:

    @Testpublic void test1() {// 创建一个 User 对象User user = new User();user.setUsername("wen");user.setAge(18);user.setPassword("123456");user.setTags("Java,Python,C++");// 转换UserVo userVo = converter.convert(user, UserVo.class);System.out.println(userVo);}

3.运行结果

四、工具类

package com.ailian.common.core.utils;import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import io.github.linpeilie.Converter;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;import java.util.List;
import java.util.Map;/*** Mapstruct 工具类* <p>参考文档:<a href="https://mapstruct.plus/introduction/quick-start.html">mapstruct-plus</a></p>*** @author Michelle.Chung*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class MapstructUtils {private final static Converter CONVERTER = SpringUtils.getBean(Converter.class);/*** 将 T 类型对象,转换为 desc 类型的对象并返回** @param source 数据来源实体* @param desc   描述对象 转换后的对象* @return desc*/public static <T, V> V convert(T source, Class<V> desc) {if (ObjectUtil.isNull(source)) {return null;}if (ObjectUtil.isNull(desc)) {return null;}return CONVERTER.convert(source, desc);}/*** 将 T 类型对象,按照配置的映射字段规则,给 desc 类型的对象赋值并返回 desc 对象** @param source 数据来源实体* @param desc   转换后的对象* @return desc*/public static <T, V> V convert(T source, V desc) {if (ObjectUtil.isNull(source)) {return null;}if (ObjectUtil.isNull(desc)) {return null;}return CONVERTER.convert(source, desc);}/*** 将 T 类型的集合,转换为 desc 类型的集合并返回** @param sourceList 数据来源实体列表* @param desc       描述对象 转换后的对象* @return desc*/public static <T, V> List<V> convert(List<T> sourceList, Class<V> desc) {if (ObjectUtil.isNull(sourceList)) {return null;}if (CollUtil.isEmpty(sourceList)) {return CollUtil.newArrayList();}return CONVERTER.convert(sourceList, desc);}/*** 将 Map 转换为 beanClass 类型的集合并返回** @param map       数据来源* @param beanClass bean类* @return bean对象*/public static <T> T convert(Map<String, Object> map, Class<T> beanClass) {if (MapUtil.isEmpty(map)) {return null;}if (ObjectUtil.isNull(beanClass)) {return null;}return CONVERTER.convert(map, beanClass);}}

总结

MapStruct Plus的用法还有很多,例如:Map转对象、类型转换、一个类与多个类之间转换、类循

环嵌套、类转换API等,具体可以看官网文档。

MapStruct Plus官网:MapStructPlus

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

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词