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

 更新时间:2021年09月18日 08:39:33   作者:机智的爆爆哥  
MapStruct 是一个代码生成器,简化了不同的 Java Bean 之间映射的处理,所谓的映射指的就是从一个实体变化成一个实体。接下来通过本文给大家介绍SpringBoot + MapStruct 属性映射工具的使用,需要的朋友可以参考下

1. MapStruct 是什么?

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

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

官方github链接 点击跳转

2. 引入依赖

采用Mapstruct的 最新版本 1.4.2.Final

SpringBoot版本不要选新版的 我对比了下 2.3.02.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属性映射工具内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:

相关文章

  • Spring配置多数据源切换

    Spring配置多数据源切换

    今天小编就为大家分享一篇关于Spring配置多数据源切换,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • MyBatis传递多个参数方式

    MyBatis传递多个参数方式

    这篇文章主要介绍了MyBatis传递多个参数方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-02-02
  • JavaSwing FlowLayout 流式布局的实现

    JavaSwing FlowLayout 流式布局的实现

    这篇文章主要介绍了JavaSwing FlowLayout 流式布局的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-12-12
  • 详谈java命令的本质逻辑揭秘

    详谈java命令的本质逻辑揭秘

    一个简单的java命令背后究竟做了些什么事情,很多朋友提出几个问题,下面带领大家一起学习Java命令的本质逻辑问题,感兴趣的朋友跟随小编一起看看吧
    2021-05-05
  • 使用IDEA查看jar包及jar包的正确打开方式

    使用IDEA查看jar包及jar包的正确打开方式

    IDEA 是把 jar 包添加为 Libraries,然后展开后即可查看,因为是编译后的 class 文件,所以注释是没有的,今天小编给大家介绍下使用IDEA查看jar包及jar包的正确打开方式,感兴趣的朋友一起看看吧
    2023-07-07
  • IDEA报错:Process terminated的问题及解决

    IDEA报错:Process terminated的问题及解决

    这篇文章主要介绍了IDEA报错:Process terminated的问题及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • Java多线程中Callable和Future的解读

    Java多线程中Callable和Future的解读

    这篇文章主要介绍了Java多线程中Callable和Future的解读,Callable接口类似于Runnable,从名字就可以看出来了,但是Runnable不会返回结果,并且无法抛出返回结果的异常,而Callable功能更强大一些,被线程执行后,可以返回值,这个返回值可以被Future拿到,需要的朋友可以参考下
    2023-09-09
  • JDK21无法导入TimeUnit类的解决办法

    JDK21无法导入TimeUnit类的解决办法

    这篇文章主要给大家介绍了关于JDK21无法导入TimeUnit类的解决办法,TimeUnit是java.util.concurrent包下面的一个类,TimeUnit提供了可读性更好的线程暂停操作,通常用来替换Thread.sleep(),需要的朋友可以参考下
    2024-01-01
  • 浅谈Java变量赋值运算符及相关实例

    浅谈Java变量赋值运算符及相关实例

    这篇文章主要介绍了Java赋值运算符的一些知识,需要的朋友可以参考下。
    2017-09-09
  • Spring Bean配置方式总结

    Spring Bean配置方式总结

    定义Spring Bcan的3种方式分别是:基于XML 的方式配置、基于注解扫播方式配置、基于元数据类的配置,本文就通过代码示例给大家详细讲讲这三种配置方式,需要的朋友可以参考下
    2023-12-12

最新评论