我们都知道,随着一个项目越来越成熟,模块的划分也会越来越细。实体类一般存放在领域中,但是领域项目不应该被其他项目依赖,所以其他项目想要获取实体类数据时,需要在每个项目中写一个模型,自定义模型即可根据自身业务需要映射相应的实体属性。这样一来,测绘工程就显得不简单了。阿粉差点遇到问题...前言那么阿粉今天给大家带来一个插件叫mapstruct,专门用来处理domin实体类和模型类之间的属性映射。我们只需要定义mapper接口,mapstruct在编译的时候会自动帮我们实现这个映射接口,避免了麻烦复杂的映射实现。那么有的朋友可能要问了?为什么不用BeanUtils的copyProperties方法呢?不是可以实现属性的映射吗?这个啊,阿凡,一开始我也很好奇,于是和BeanUtils进行了深入的交流,最后发现BeanUtils是个大佬,只能映射到同一个属性,或者在case中对于相同的属性,它允许映射更少的对象属性;但是当映射的属性数据类型被修改或者映射的字段名被修改时,会导致映射失败。而mapstruct是个聪明的儿媳妇。她心思细腻,把我们可能遇到的各种情况都考虑到了(要是能找到这样的媳妇就好了,心里笑成猪了)如下是的本插件开源项目地址及各种示例:Github地址:https://github.com/mapstruct/mapstruct/使用示例:https://github.com/mapstruct/mapstruct-examples一、准备工作接下来,阿芬会和大家一起揭开这个机灵儿媳妇的真实面纱,所以我们还需要做一些准备工作。1.1.理解@Mapper注解。mybatis3.4.0加入的@Mapper注解是不再写mapper映射文件。我们只需要在dao层定义的接口上使用注解即可实现sql语句的编写,例如:@Select("select*fromuserwherename=#{name}")publicUserfind(Stringname);以上是一个简单的使用,虽然简单,但是确实体现了这个注解的优越性,至少少写了一个xml文件。不过阿粉,我今天不想和你讨论@Mapper注解。主要是想看看我机灵的老婆mapstruct,所以我只想说说@Mapper注解的componentModel属性。componentModel属性用于指定自动生成的接口实现类的组件类型。该属性支持四个值:default:这是默认情况。mapstruct不使用任何组件类型,可以通过Mappers.getMapper(Class)获取自动生成的实例对象。cdi:生成的mapper是一个application-scopedCDIbean,可以通过@Injectspring获取:@Component注解会自动添加到生成的实现类中,可以通过Spring的@Autowired方法注入。jsr330:在生成的实现类上会添加@javax.inject.Named和@Singleton注解,可以通过@Inject注解1.2获取。依赖包首先需要导入依赖包,主要由两个包组成:org.mapstruct:mapstruct:包含一些必要的注解,例如@Mapping。r如果我们使用的JDK版本高于1.8,我们在pom中引入依赖时,建议使用坐标:org.mapstruct:mapstruct-jdk8,这样可以帮助我们利用Java8的一些新特性。org.mapstruct:mapstruct-processor:注解处理器,根据注解自动生成mapper实现。org.mapstructmapstruct-jdk81.2.0.Finalorg.mapstructmapstruct-processor1.2.0.Final好了,准备工作做好了,接下来我们看看聪明的儿媳妇在哪里。2.简单玩一下2.1.定义实体类和映射类//实体类@Data@NoArgsConstructor@AllArgsConstructor@BuilderpublicclassUser{privateIntegerid;privateStringname;privateStringcreateTime;privateLocalDateTimeupdateTime;}//映射类VO1:与实体类完全一样@Data@NoArgsConstructor@AllArgsConstructor@BuilderpublicclassUserVO1{privateIntegerid;privateStringname;privateStringcreateTime;privateLocalDateTimeupdateTime;}//映射类VO1:比实体类少一个字段@Data@NoArgsConstructor@AllArgsConstructor@BuilderpublicclassUserVO2{privateIntegerid;privateString2name;privateStringname}接口定义;:当实体类与映射对象属性相同或映射对象属性值较小时:@Mapper(componentModel="spring")publicinterfaceUserCovertBasic{UserCovertBasicINSTANCE=Mappers.getMapper(UserCovertBasic.class);/***字段数量type数量相同,也可以使用工具BeanUtils实现类似的效果*@paramsource*@return*/UserVO1toConvertVO1(Usersource);UserfromConvertEntity1(UserVO1userVO1);/***字段数量相同类型,而且数量少:只能把more转换成less,所以没有fromConvertEntity2*@paramsource*@return*/UserVO2toConvertVO2(Usersource);}从上面的代码可以看出,声明了一个成员变量INSTANCE接口,父级是让客户客户端可以访问Mapper接口的实现2.3.使用@RestControllerpublicclassTestController{@GetMapping("convert")publicObjectconvertEntity(){Useruser=User.builder().id(1).name("张三").createTime("2020-04-0111:05:07").updateTime(LocalDateTime.now()).build();List