Mapstruct 映射:如果所有源参数属性为空,则返回空对象

Posted

技术标签:

【中文标题】Mapstruct 映射:如果所有源参数属性为空,则返回空对象【英文标题】:Mapstruct Mapping : Return null object if all source parameters properties are null 【发布时间】:2022-01-07 23:43:44 【问题描述】:

如果@Mapping/source 中引用的所有属性都为null,我希望生成的mapstruct 映射方法返回null。 例如,我有以下映射:

@Mappings(
      @Mapping(target = "id", source = "tagRecord.tagId"),
      @Mapping(target = "label", source = "tagRecord.tagLabel")
)
Tag mapToBean(TagRecord tagRecord);

然后生成的方法是:

public Tag mapToBean(TagRecord tagRecord) 
    if ( tagRecord == null ) 
        return null;
    

    Tag tag_ = new Tag();

    if ( tagRecord.getTagId() != null ) 
        tag_.setId( tagRecord.getTagId() );
    
    if ( tagRecord.getTagLabel() != null ) 
        tag_.setLabel( tagRecord.getTagLabel() );
    

    return tag_;

测试用例:TagRecord 对象不为空,但有 tagId==null 和 tagLibelle==null。

当前行为:返回的 Tag 对象不为 null,但有 tagId==null 和 tagLibelle==null

如果(tagRecord.getTagId() == null && tagRecord.getTagLabel() == null),我真正想要生成的方法做的是返回一个空的 Tag 对象。 有可能吗?我该如何实现?

【问题讨论】:

【参考方案1】:

目前 MapStruct 不直接支持此功能。但是,您可以在Decorators 的帮助下实现您想要的,并且您必须手动检查所有字段是否为空并返回null 而不是对象。

@Mapper
@DecoratedWith(TagMapperDecorator.class)
public interface TagMapper 
    @Mappings(
        @Mapping(target = "id", source = "tagId"),
        @Mapping(target = "label", source = "tagLabel")
    )
    Tag mapToBean(TagRecord tagRecord);



public abstract class TagMapperDecorator implements TagMapper 

    private final TagMapper delegate;

    public TagMapperDecorator(TagMapper delegate) 
        this.delegate = delegate;
    

    @Override
    public Tag mapToBean(TagRecord tagRecord) 
        Tag tag = delegate.mapToBean( tagRecord);

        if (tag != null && tag.getId() == null && tag.getLabel() == null) 
            return null;
         else 
            return tag;
        
    

我编写的示例(构造函数)适用于使用default 组件模型的映射器。如果您需要使用 Spring 或其他 DI 框架,请查看:

Decorators with Spring Decorators with JSR 330 如果使用 CDI,则不应使用 @DecoratedWith,而应使用 CDI Decorators

【讨论】:

以上是关于Mapstruct 映射:如果所有源参数属性为空,则返回空对象的主要内容,如果未能解决你的问题,请参考以下文章

MapStruct使用说明

Mapstruct:抽象源类错误:没有属性命名

MapStruct 一文读懂

Spring Boot | 集成MapStruct实现不同类型Java对象间的自动转换

在 MapStruct 中使用多源对象设置默认值策略

mapstruct使用指南