SpringBoot + MapStruct 属性映射工具的使用详解
作者:机智的爆爆哥
1. MapStruct 是什么?
截取下官方的原话 我给翻译了一下 说白了 当你的对象A有几十个属性 而另一个对象B 与A比较只有一些细微的差别
那么这时候只需要映射过去即可 而不需要疯狂的调用set方法 进行属性的拷贝 这就是这个工具给我们带来的最大便利
官方github链接 点击跳转
2. 引入依赖
采用Mapstruct的 最新版本 1.4.2.Final
SpringBoot
版本不要选新版的 我对比了下 2.3.0
和 2.5.4
后者会出现属性映射为null的情况
已经将问题反馈了 具体不知道是和原因 所以先用老版本吧
下面的插件最好与我的保持一致 否则会导致一些问题
<properties> <java.version>1.8</java.version> <mapstruct.version>1.4.2.Final</mapstruct.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct</artifactId> <version>${mapstruct.version}</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>${java.version}</source> <target>${java.version}</target> <annotationProcessorPaths> <!-- 引入 mapstruct-processor --> <path> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-processor</artifactId> <version>${mapstruct.version}</version> </path> <!-- 引入 lombok-processor --> <path> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${lombok.version}</version> </path> </annotationProcessorPaths> </configuration> </plugin> </plugins> </build>
3.当两个对象属性完全相同时 User 类
新建 User
类 随便加点属性进去
@Data @Accessors(chain = true) public class User { private String name; private String password; private String money; }
UserVo 类
再新建一个我们需要拷贝过去的对象 UserVo
属性完全相同
@Data @Accessors(chain = true) public class UserVo { private String name; private String password; private String money; }
转换接口 UserConvert
@Mapper// 注意 这里的注解是org.mapstruct包下的 public interface UserConvert { //默认写法 调用getMapper 获取对应的实体类 编译后会生成对应的实现类 UserConvert INSTANCE = Mappers.getMapper(UserConvert.class); UserVo convert(User user); }
我们将代码编译一下 在 target
目录下 找到对应的实现类 UserConvertImpl
可以发现他其实就是将对应的属性设置到了 Vo对象中罢了 只不过这是自动生成的
public class UserConvertImpl implements UserConvert { public UserConvertImpl() { } public UserVo convert(User user) { if (user == null) { return null; } else { UserVo userVo = new UserVo(); userVo.setName(user.getName()); userVo.setPassword(user.getPassword()); userVo.setMoney(user.getMoney()); return userVo; } } }
测试属性赋值
在对应的测试类里 转化打印
@Test void contextLoads() { User user = new User().setName("爆爆").setPassword("123").setMoney("500"); UserVo userVo = UserConvert.INSTANCE.convert(user); System.out.println(userVo); }
打印结果如下
UserVo(name=爆爆, password=123, money=500)
4. 当对象属性有所差别时 UserVo2
对应的User
不变 新增 一个 UserVo2
将原先的name改成了UserName
@Data @Accessors(chain = true) public class UserVo2 { //name--->userName private String userName; private String password; private String money; }
这时候我们要将User的属性值直接赋予 其实是不会报错的 只不过name
不会映射给UserName
而已
修改转换类
@Mapper// 注意 这里的注解是org.mapstruct包下的 public interface UserConvert { //默认写法 调用getMapper 获取对应的实体类 编译后会生成对应的实现类 UserConvert INSTANCE = Mappers.getMapper(UserConvert.class); UserVo convert(User user); //新增一个方法 UserVo2 convert2(User user); }
再次测试
@Test void contextLoads() { User user = new User().setName("爆爆").setPassword("123").setMoney("500"); UserVo2 userVo2 = UserConvert.INSTANCE.convert2(user); System.out.println(userVo2); }
打印结果
UserVo2(userName=null, password=123, money=500)
如果要要将 name 赋值给 userName 其实也很简单 操作如下
新增 @Mappings
与@Mapping
注解 指明对应哪个属性赋值给哪个就可以了
@Mapper// 注意 这里的注解是org.mapstruct包下的 public interface UserConvert { //默认写法 调用getMapper 获取对应的实体类 编译后会生成对应的实现类 UserConvert INSTANCE = Mappers.getMapper(UserConvert.class); UserVo convert(User user); @Mappings({ //对应 source指向的是User targer指向的是UserVo2 @Mapping(source = "name",target = "userName") }) UserVo2 convert2(User user); }
再次运行测试类
打印结果 发现没有问题
UserVo2(userName=爆爆, password=123, money=500)
5. IDEA插件
mapstrut有对应的idea插件 其实我觉得作用一般吧 还是放上吧
由于自己研究的也不多 暂时写到这里
我们执着于那些遗憾,并非那些事情有多重要,而是那些时光里的自己,是真诚坦率且可爱的,也许这才是我们执着的意义。
到此这篇关于SpringBoot + MapStruct 属性映射工具的使用的文章就介绍到这了,更多相关SpringBoot属性映射工具内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!