MapStruct表达式应用及避坑详解
目录
- 前言
- 遇到的问题
- 发现原因
- 结语
前言
生成的映射代码使用简单的方法调用,因此速度快,类型安全且易于理解。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表达式避坑的资料请关注我们其它相关文章!
相关推荐
-
MapStruct到底是什么?
一.简介 现在的分布式系统中模块划分越来越细,不同模块的实体.DTO.DO等需要进行转换,这么多工程处理起来不是那么简单. MapStruct 就是这样的一个属性映射插件,用于为Java Bean生成类型安全且高性能的映射.它基于编译阶段生成get/set代码,此实现过程中没有反射,不会造成额外的性能损失.只需要定义一个 Mapper 接口,MapStruct 就会自动实现这个映射接口,避免了繁琐的映射实现.
-
解析MapStruct转换javaBean时出现的诡异事件
在项目中用到了MapStruct,对其可以转换JavaBean特别好奇,因为之前都是使用Vo的方式手动set转换,但是接触到MapStruct后感觉以前使用Vo的方式确实有点low 于是就想着去看一下,写了个demo.于是这诡异的时间就开始了 我得代码如下: 这是pom文件 这是我的两个javaBean 大家可以看到那个发灰的序列化接口,那是因为我再运行出结果是转换后的JavaBean属性为空,我以为是序列化时导致的所以我去掉了, 可是后来发现完全不是这个原因 这是我的mapper转换类 还有我
-
Java MapStruct解了对象映射的毒
前言 MVC模式是目前主流项目的标准开发模式,这种模式下框架的分层结构清晰,主要分为Controller,Service,Dao.分层的结构下,各层之间的数据传输要求就会存在差异,我们不能用一个对象来贯穿3层,这样不符合开发规范且不够灵活. 我们常常会遇到层级之间字段格式需求不一致的情况,例如数据库中某个字段是datetime日期格式,这个时间戳在数据库中的存储值为2020-11-06 23:59:59.999999,但是传递给前端的时候要求接口返回yyyy-MM-dd的格式,或者有些数据在数据
-
MapStruct实体间转换的简单用法
摘要: 在实际项目中,我们经常需要将PO转DTO.DTO转PO等一些实体间的转换.比较出名的有BeanUtil 和ModelMapper等,它们使用简单,但是在稍显复杂的业务场景下力不从心.MapStruct这个插件可以用来处理domin实体类与model类的属性映射,可配置性强. 建立Maven项目 MapStruct需要醒目构建工具(如Maven)支持,如果项目结构不标准,可能无法生成对应的转换类.这里我使用Maven构建工程. <properties> <org.mapstruct
-
Java实体映射工具MapStruct使用方法详解
目录 1.序 2.简单用例 3.使用详解 1)关于接口注解@Mapper几种属性用法详解 2) 其他方法级别注解 总结 1.序 通常在后端开发中经常不直接返回实体Entity类,经过处理转换返回前端,前端提交过来的对象也需要经过转换Entity实体才做存储:通常使用的BeanUtils.copyProperties方法也比较粗暴,不仅效率低下(使用反射)而且仅映射相同名的属性,多数情况下还需要手动编写对应的转换方法实现. 插件MapStruct以接口方法结合注解优雅实现对象转换,MapStruc
-
MapStruct表达式应用及避坑详解
目录 前言 遇到的问题 发现原因 结语 前言 生成的映射代码使用简单的方法调用,因此速度快,类型安全且易于理解.MapStruct的表达式功能是为了处理特殊对象属性的映射问题,比如DTO中的status属性转换成PO中的status需要进一步的处理,这个时候就需要用到表达式功能了.这里不再赘述关于MapStruct的使用问题,更多的使用教程可参考文档 MapStruct官方文档:https://mapstruct.org/documentation/stable/reference/html/#
-
java开发使用StringUtils.split避坑详解
目录 正文 StringUtils.split 的坑 StringUtils.split 源码分析 如何解决? 正文 在日常的 Java 开发中,由于 JDK 未能提供足够的常用的操作类库,通常我们会引入 Apache Commons Lang 工具库或者 Google Guava 工具库简化开发过程.两个类库都为 java.lang API 提供了很多实用工具,比如经常使用的字符串操作,基本数值操作.时间操作.对象反射以及并发操作等. <dependency> <groupId>
-
OGNL表达式基本语法与用法详解
一.OGNL中的#.%和$符号 #.%和$符号在OGNL表达式中经常出现,而这三种符号也是开发者不容易掌握和理解的部分.在这里我们简单介绍它们的相应用途. 1.#符号的三种用法 1)访问非根对象属性,例如示例中的#session.msg表达式,由于Struts 2中值栈被视为根对象,所以访问其他非根对象时,需要加#前缀.实际上,#相当于ActionContext. getContext():#session.msg表达式相当于ActionContext.getContext().getSessi
-
C# 表达式目录树的应用详解
使用表达式目录树实现两个不同类型的属性赋值: public class People { public int Age { get; set; } public string Name { get; set; } public int Id; } public class PeopleCopy { public int Age { get; set; } public string Name { get; set; } public int Id; } public class Class1 {
-
Django model重写save方法及update踩坑详解
一个非常实用的小方法 试想一下,Django中如果我们想对保存进数据库的数据做校验,有哪些实现的方法? 我们可以在view中去处理,每当view接收请求,就对提交的数据做校验,校验不通过直接返回错误,不写数据库,校验通过再调用create或update方法写入数据库 以上方式比较简单,容易理解,但随之又带来了麻烦,我们需在所有接收数据的地方都要去校验,那么有没有更加优雅的方式呢?如果你看过我之前的文章『Django使用Signals监测model字段变化发送通知』]就能想到可以通过signals
-
mapstruct的用法之qualifiedByName示例详解
qualifiedByName的意思就是使用这个Mapper接口中的指定的默认方法去处理这个属性的转换,而不是简单的get set.网上一直没找到… 可用于格式化小数位等,在po转换为vo时就已格式化小数位完成,所以不必单独再写代码处理小数位. 1 引用pom1 ,能正常使用mapstruct的注解,但不会生成Impl类 <!-- https://mvnrepository.com/artifact/org.mapstruct/mapstruct-jdk8 --> <dependency
-
vue实例成员 插值表达式 过滤器基础教程示例详解
目录 一. 什么是Vue 二.为什么学Vue 三.如何使用Vue 下载安装? 插值表达式 四.vue特点 1.虚拟DOM 2.数据的双向绑定 3.单页面应用 4.数据驱动 五.Vue实例 六.实例成员 - 挂载点 | el - 自定义插值表达式括号| delimiters - 数据 | data - 过滤器 | filters - 方法 | methods - js对象(即字典)补充 - 插值表达式转义 | delimters - 计算属性 | computed - 监听属性 | watch 一
-
JSON.stringify实现深拷贝的巨坑详解
目录 当对象中有时间类型的元素时候-----时间类型会被变成字符串类型数据 当对象中有undefined类型或function类型的数据时 --- undefined和function会直接丢失 当对象中有NaN.Infinity和-Infinity这三种值的时候 --- 会变成null 当对象循环引用的时候 --会报错 总结 当对象中有时间类型的元素时候-----时间类型会被变成字符串类型数据 const obj = { date:new Date() } typeof obj.date ==
-
浅试仿 mapstruct实现微服务编排框架详解
目录 微服务编排框架 开发背景 接口的方式 通过注解的方式 书写代码方式的选择 方案选择 feign MapStruct 方案总结 Feign @FeignClient MapStruct 微服务编排框架 起始原因 是 我们公司 分布式事务 使用的是 seate 分布式事务框架,现在只在一些小部分使用,因为考虑到seate 对性能 TCP的影响,对事务这块没有更多的选择.我就在想 是不是做一个 微服务 编排框架 来解决这个问题.这里就 开发背景 因为我们是saas 可能A企业要这个功能,B企业不
-
Laravel Intervention/image图片处理扩展包的安装、使用与可能遇到的坑详解
前言 Intervention/image 是为 Laravel 定制的图片处理工具, 它提供了一套易于表达的方式来创建.编辑图片. Demo 代码请见: Github:https://github.com/zhengjinghua/est-image-demo 本地下载:http://xiazai.jb51.net/201711/yuanma/est-image-demo(jb51.net).rar Demo Demo 截图 Demo 运行 请参照文档 如何利用 Homestead 快速运行一
随机推荐
- Angular.JS通过指令操作DOM的方法
- jquery实现效果比较好的table选中行颜色
- jQuery动画与特效详解
- JQuery制作的放大效果的popup对话框(未添加任何jquery plugin)分享
- Oracle Portal及其门户网站开发概述
- python改变日志(logging)存放位置的示例
- Python抽象类的新写法
- asp.net生成高质量缩略图通用函数(c#代码),支持多种生成方式
- PHP输出缓冲控制Output Control系列函数详解
- laravel 5.1下php artisan migrate的使用注意事项总结
- Win7下搭建python开发环境图文教程(安装Python、pip、解释器)
- Android实现微信朋友圈发本地视频功能
- JavaScript toUpperCase()方法使用详解
- PHP的简易冒泡法代码分享
- DIV+CSS+jQ实现省市联动可扩展
- jQuery Validate验证框架详解(推荐)
- Python使用QQ邮箱发送Email的方法实例
- 读jQuery之三(构建选择器)
- 分享一个自己写的简单的javascript分页组件
- Redis 订阅发布_Jedis实现方法