平时做项目的时候,经常需要做PO、VO、DTO之间的转换。简单的对象转换,使用BeanUtils基本上是够了,但是复杂的转换,如果使用它的话又得写一堆Getter、Setter方法了。今天给大家推荐一款对象自动映射工具MapStruct,功能真心强大!
关于BeanUtils
平时我经常使用Hutool中的BeanUtil类来实现对象转换,用多了之后就发现有些缺点:
-
对象属性映射使用反射来实现,性能比较低;
-
对于不同名称或不同类型的属性无法转换,还得单独写Getter、Setter方法;
-
对于嵌套的子对象也需要转换的情况,也得自行处理;
-
集合对象转换时,得使用循环,一个个拷贝。
对于这些不足,MapStruct都能解决,不愧为一款功能强大的对象映射工具!
MapStruct简介
MapStruct是一款基于Java注解的对象属性映射工具,在Github上已经有4.5K+Star。使用的时候我们只要在接口中定义好对象属性映射规则,它就能自动生成映射实现类,不使用反射,性能优秀,能实现各种复杂映射。
IDEA插件支持
作为一款非常流行的对象映射工具,MapStruct还提供了专门的IDEA插件,我们在使用之前可以先安装好插件。
在SpingBoot中集成MapStruct非常简单,仅续添加如下两个依赖即可,这里使用的是1.4.2.Final版本。
<dependency> <!--MapStruct相关依赖--> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct</artifactId> <version>${mapstruct.version}</version> </dependency> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-processor</artifactId> <version>${mapstruct.version}</version> <scope>compile</scope> </dependency></dependencies>
基本使用
集成完MapStruct之后,我们来体验下它的功能吧,看看它有何神奇之处!
基本映射
我们先来个快速入门,体验一下MapStruct的基本功能,并聊聊它的实现原理。
-
首先我们准备好要使用的会员PO对象Member;
/** * 购物会员 * Created by macro on 2021/10/12. */@Data@EqualsAndHashCode(callSuper = false)public class Member { private Long id; private String username; private String password; private String nickname; private Date birthday; private String phone; private String icon; private Integer gender;}
-
然后再准备好会员的DTO对象MemberDto,我们需要将Member对象转换为MemberDto对象;
/** * 购物会员Dto * Created by macro on 2021/10/12. */@Data@EqualsAndHashCode(callSuper = false)public class MemberDto { private Long id; private String username; private String password; private String nickname; //与PO类型不同的属性 private String birthday; //与PO名称不同的属性 private String phoneNumber; private String icon; private Integer gender;}
-
然后创建一个映射接口MemberMapper,实现同名同类型属性、不同名称属性、不同类型属性的映射;
/** * 会员对象映射 * Created by macro on 2021/10/21. */@Mapperpublic interface MemberMapper { MemberMapper INSTANCE = Mappers.getMapper(MemberMapper.class); @Mapping(source = "phone",target = "phoneNumber") @Mapping(source = "birthday",target = "birthday",dateFormat = "yyyy-MM-dd") MemberDto toDto(Member member);}
-
接下来在Controller中创建测试接口,直接通过接口中的INSTANCE实例调用转换方法toDto;
/** * MapStruct对象转换测试Controller * Created by macro on 2021/10/21. */@RestController@Api(tags = "MapStructController", description = "MapStruct对象转换测试")@RequestMapping("/mapStruct")public class MapStructController { @ApiOperation(value = "基本映射") @GetMapping("/baseMapping") public CommonResult baseTest() { List<Member> memberList = LocalJsonUtil.getListFromJson("json/members.json", Member.class); MemberDto memberDto = MemberMapper.INSTANCE.toDto(memberList.get(0)); return CommonResult.success(memberDto); }}
-
运行项目后在Swagger中测试接口,发现PO所有属性已经成功转换到DTO中去了,Swagger访问地址:http://localhost:8088/swagger-ui