SpringBoot + MapStruct 属性映射工具的使用详解

网友投稿 1461 2022-12-07

SpringBoot + MapStruct 属性映射工具的使用详解

1. MapStruct 是什么?

截取下官方的原话 我给翻译了一下 说白了 当你的对象A有几十个属性 而另一个对象B 与A比较只有一些细微的差别

那么这时候只需要映射过去即可 而不需要疯狂的调用set方法 进行属性的拷贝 这就是这个工具给我们带来的最大便利

官方github链接 点击跳转

2. 引入依赖

采用Mapstruct的 最新版本 1.4.2.Final

SpringBoot版本不要选新版的 我对比了下 2.3.0 和 2.5.4 后者会出现属性映射为null的情况

已经将问题反馈了 具体不知道是和原因 所以先用老版本吧

下面的插件最好与我的保持一致 否则会导致一些问题

1.8

1.4.2.Final

org.springframework.boot

spring-boot-starter

org.mapstruct

mapstruct

${mapstruct.version}

org.projectlombok

lombok

org.springframework.boot

spring-boot-starter-test

test

org.apache.maven.plugins

maven-compiler-plugin

3.8.1

${java.version}

${java.version}

org.mapstruct

mapstruct-processor

${mapstruct.version}

org.projectlombok

lombok

${lombok.version}

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插件 其实我觉得作用一般吧 还是放上吧

插件链接

由于自己研究的也不多 暂时写到这里

我们执着于那些遗憾,并非那些事情有多重要,而是那些时光里的自己,是真诚坦率且可爱的,也许这才是我们执着的意义。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java Integer对象的比较方式
下一篇:Java中关于二叉树层序遍历深入了解
相关文章

 发表评论

暂时没有评论,来抢沙发吧~