MapStruct表达式应用及避坑详解

 更新时间:2022年02月22日 16:57:24   作者:kl  
一不小心踩了MapStruct表达式的坑,发现了一个在官方文档上都找不到的功能,有必要记录下。MapStruct是一个代码生成器,它基于约定优于配置的方法大大简化了Java Bean类型之间的映射的实现

前言

生成的映射代码使用简单的方法调用,因此速度快,类型安全且易于理解。MapStruct的表达式功能是为了处理特殊对象属性的映射问题,比如DTO中的status属性转换成PO中的status需要进一步的处理,这个时候就需要用到表达式功能了。这里不再赘述关于MapStruct的使用问题,更多的使用教程可参考文档

MapStruct官方文档:https://mapstruct.org/documentation/stable/reference/html/#mapping-composition

遇到的问题

先看一段映射的代码:

@Mapper(imports = CustomProcessors.class)
public interface DepartmentsMapper {
    @Mapping(target = "status", expression = "java( DepartmentsMapper.toStatus(department.getStatus()) )")
    DepartmentsVO boToVo(DepartmentBO department);
    static String toStatus(String status){
        return status + "状态";
    }
}

原本这段代码表达的语义是:将DepartmentBO的status属性赋值给DepartmentsVO时,需要进行一些简单的转换,转换的方法就是Mapper接口里定义的toStatus静态方法。可最终MapStruct生成的代码把其他属性的赋值动作也做了处理。生成的代码如下:

可以看到除了指定的status属性加上了表达式中的代码,其他的属性也都加上了,这不是我们想要的效果。

发现原因

楼主反复查看官方文档,最后就差把源码拉下来看实现逻辑了,最后一个闪念猜想到了可能的原因。上面关于表达式的使用代码没有问题,官方文档也写的很清楚。主要是因为这里触发了MapStruct的一个隐藏功能:仔细观察生成的代码发现,只有Integer属性的字段加上表达式中的代码了,楼主推断只要在定义maping的接口中定义了转换方法就会被自动应用到相同类型属性的转换上。后面验证确实如此,比如我去掉表达式的定义:

@Mapper(imports = CustomProcessors.class)
public interface DepartmentsMapper {
    DepartmentsVO boToVo(DepartmentBO department);
    static Integer toStatus(Integer status){
        return status + 1;
    }
}

最终生成的代码还是所有的Integer属性的值都加上了toStatus的处理了

结语

最后发现的这个特性竟然在官方文档上找不到丝毫的描述,其实可以算一个非常不错的功能,可以统一处理相同类型的属性,比如属性是一个对象时,只是在博主的这个场景下使用不到。最后的解决方案是将表达式中的代码定义从Mapper接口中移出去就好了。

以上就是MapStruct表达式应用及避坑详解的详细内容,更多关于MapStruct表达式避坑的资料请关注脚本之家其它相关文章!

相关文章

  • JVM性能调优之运行时参数小结

    JVM性能调优之运行时参数小结

    jvm是java的运行环境,在jvm中有很多的参数可以进行设置,本文主要介绍了JVM性能调优之运行时参数小结,具有一定的参考价值,感兴趣的可以了解一下
    2024-04-04
  • Spring boot RedisTemplate 序列化服务化配置方式

    Spring boot RedisTemplate 序列化服务化配置方式

    这篇文章主要介绍了Springboot RedisTemplate序列化服务化配置方式,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-07-07
  • Java中的hashcode方法介绍

    Java中的hashcode方法介绍

    这篇文章主要介绍了Java中的hashcode方法介绍,还是比较不错的,这里分享给大家,供需要的朋友参考。
    2017-11-11
  • 详解java重载与覆写的区别

    详解java重载与覆写的区别

    很多同学会重载和重写分不清楚,这篇文章主要介绍了详解java重载与覆写的区别,有需要的朋友可以了解一下。
    2016-11-11
  • 如何使用spring ResponseEntity处理http响应

    如何使用spring ResponseEntity处理http响应

    这篇文章主要介绍了如何使用spring ResponseEntity处理http响应的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • python和java哪个学起来更简单

    python和java哪个学起来更简单

    在本篇内容里小编给大家分享的是一篇关于python和java哪个学起来更简单的相关内容,有兴趣的朋友们参考下。
    2020-06-06
  • SpringBoot实现热部署详解

    SpringBoot实现热部署详解

    SpringBoot热部署是一种开发时极为有用的功能,它能够让开发人员在代码修改后无需手动重启应用程序就能立即看到变化的效果,所以我本文就给打击介绍一下为什么要使用热部署以及实现热部署的方式,需要的朋友可以参考下
    2023-07-07
  • Springboot与vue实例讲解实现前后端分离的人事管理系统

    Springboot与vue实例讲解实现前后端分离的人事管理系统

    这篇文章主要介绍了如何用Java实现企业人事管理系统,文中采用springboot+vue实现前后端分离,感兴趣的小伙伴可以学习一下
    2022-06-06
  • MyBatis Plus 将查询结果封装到指定实体的方法步骤

    MyBatis Plus 将查询结果封装到指定实体的方法步骤

    这篇文章主要介绍了MyBatis Plus 将查询结果封装到指定实体的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • SpringBoot集成Milvus和deeplearning4j实现图搜图功能

    SpringBoot集成Milvus和deeplearning4j实现图搜图功能

    Milvus 是一种高性能、高扩展性的向量数据库,可在从笔记本电脑到大型分布式系统等各种环境中高效运行,Deeplearning4j(DL4J)是一个开源的深度学习框架,专门为Java和Scala开发,本文给大家介绍了SpringBoot集成Milvus和deeplearning4j实现图搜图功能
    2024-10-10

最新评论