MapStruct属性多转一实现

在项目里遇到了需要使用mapstruct将source对象的多个属性转为target对象的一个属性的场景。针对这个问题研究了一段时间,发现想要解决得好一些还是挺让人头疼的。

先说结论吧:MapStruct支持将多个对象转为一个对象,但是不支持将多个属性转为一个属性。对,mapstruct是不支持这么做的。

最终的解决方案也非常简单:在使用mapstruct完成对象的简单转换后,再做一次加工就行。不过我想将这个事情做得优雅一些,目的是尽量不影响业务代码。

项目的代码不好拿出来,举个例子来说明下,在下面的代码中定义了一个产品的Entity类及相应的Item类。目标是将Entity类的实例通过mapstruct转为Item类的实例。

先看下类的定义:

产品Entity类 ProductEntity:

产品Item类 ProductItem :

ProductItem 比 ProductEntity 多了一个 status 属性,这个status属性可以由 生产日期 (manufactureDate)和保质期(qualityGranteeMonths)计算出来。计算逻辑可以看下 ProductStatusEnum 的定义及类中静态的analyze方法:

要实现基于 ProductEntity 的生产日期和保质期两个字段映射出Item的status的值,可以在完成 Entity和Item的转换后再做一次处理,类似下面的代码:

如上面的代码:在转换接口 ProductConverter 中,定义了一个default方法entity2Item,在这个方法中利用mapstruct生成的 entity2ItemSimply() 方法完成简单转换后又做了一次 生产日期、保质期和状态的映射。因为是在同一个转换接口中定义的,在使用时还是比较丝滑的。

不过有一个小问题,就是现在转换接口 ProductConverter 中存在两个将 Entity转为Item的方法,在处理相关Collection 转换时就会出现因为不知道该调用哪个方法而产生的报错,如下:

要解决这个问题也比较简单,使用 qualifyByName 进行标记即可, 最终代码如下:

对了,不要忘了给 entity2Item() 方法加上 @Name 注解,不然会报相关方法找不到的错的。

就这样。源码在这里: zhy-explore / mapstruct-explore

End !!!

发表评论

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据