当前位置: 首页 > 知识库问答 >
问题:

对所有枚举使用相同的映射器

晏望
2023-03-14

我试图将所有枚举映射到相同的DTO类,我希望避免为每个枚举类型声明一个方法,或者为每个枚举字段使用@Map

@Mapper
public interface EnumDtoMapper
{
    // approach one
    default <E extends Enum<E>> EnumDTO enumToEnumDTO(Enum<E> e)
    {
        if (e == null)
        {
            return null;
        }
        EnumDTO enumDTO = new EnumDTO();
        enumDTO.setName(e.name());
        return enumDTO;
    }

    //approach two: enum -> String -> EnumDTO
    default <E extends Enum<E>> String enumToString(Enum<E> e)
    {
        return e.name();
    }


    default EnumDTO stringToEumDTO(String name)
    {
        EnumDTO enumDTO = new EnumDTO();
        enumDTO.setName(name);
        return enumDTO;
    }
}

然后在我的其他地图上

@Mapper(componentModel = "cdi", injectionStrategy = InjectionStrategy.CONSTRUCTOR, uses = {
        EnumDtoMapper.class
})

但MapStruct仍在为每种枚举类型生成一种新的映射方法,而且实现方式不符合我的需要。

有没有办法用MapStruct做到这一点?还是太神奇了D

共有1个答案

徐皓君
2023-03-14

做了一些测试,如果没有组件模型设置为cdi,您所拥有的将生成您所期望的。但是有了它,您需要通配符输入枚举的通用类型,之后它应该可以工作。

如果EnuUtil看起来像这样:

class EnumUtil {

    static EnumDto enumToEnumDTO(Enum<?> e) {
        if ( e == null ) {
            return null;
        }
        EnumDto enumDTO = new EnumDto( e.name() );
        return enumDTO;
    }

    // approach two: enum -> String -> EnumDTO
    static String enumToString(Enum<?> e) {
        return e.name();
    }

    static EnumDto stringToEumDTO(String name) {
        return new EnumDto( name );
    }
}

使用以下映射器和类:

@Mapper( componentModel = ComponentModel.CDI,
        injectionStrategy = InjectionStrategy.CONSTRUCTOR,
        uses = {
            EnumUtil.class
        } )
public interface EnumMapper {

    @Mapping( target = "value", source = "enumValue" )
    DtoWithEnumDto map(SourceWithEnum source);
}

class SourceWithEnum {
    private MyEnum enumValue;
    // getter & setter
}

enum MyEnum {
    SOMETHING, ELSE
}

class EnumDto {
    private final String name;
    // constructor and getter
}

class DtoWithEnumDto {
    private EnumDto value;
    // constructor, getter and setter
}

您将得到以下生成的映射器:

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2022-02-21T16:59:06+0100",
    comments = "version: 1.4.2.Final, compiler: Eclipse JDT (IDE) 1.4.50.v20210914-1429, environment: Java 17.0.1 (Azul Systems, Inc.)"
)
@ApplicationScoped
public class EnumMapperImpl implements EnumMapper {

    @Override
    public DtoWithEnumDto map(SourceWithEnum source) {
        if ( source == null ) {
            return null;
        }

        EnumDto value = null;

        value = EnumUtil.enumToEnumDTO( source.getEnumValue() );

        DtoWithEnumDto dtoWithEnumDto = new DtoWithEnumDto( value );

        return dtoWithEnumDto;
    }
}
 类似资料:
  • 问题内容: 我需要预先将未实现接口的枚举映射到现有数据库,该数据库使用将该枚举存储在与所有者类相同的表中。 在这种情况下应如何处理映射?持久化到数据库不会改变,因为实现该接口的所有枚举都将具有不同的值,但是我不确定应如何从数据库中检索对象(我是否需要自定义映射器,它将尝试实例化一个使用指定的enum类进行枚举吗?Hibernate本身是否支持此功能?)。 问题答案: 可以创建一个自定义(例如thi

  • 问题内容: Hibernate提供的注释支持使用或的两种类型的映射。当我们使用映射时,它使用的“名称” 而不是Enum的表示形式。在数据库列仅包含一个字符的情况下,这是一个问题。例如,我有以下枚举: 当我坚持枚举使用,即hibernate尝试在数据库中存储的值是开放的。但是,我的数据库列仅包含一个字符,因此会引发异常。 克服这个问题的一个办法是改变枚举类型持有单个字符(如,代替,)。但是,这降低了

  • 我想映射2个模型,其中每个模型都有几乎相同的枚举。让我展示: 第一个模型有枚举: 第二个模型具有枚举: 我有这样的自定义映射方法: 然后我用: 但是你可以得到: 我还创建了枚举映射器,如: 但我不需要单独设置,只希望枚举字段映射到内部映射中。简单地说,当我做枚举时,也应该映射。 谢谢 p、 对不起我的英语,希望我的问题有意义:)

  • 我有一个实体,有一个枚举类型字段和一个具有相同枚举类型和字段名的DTO。 我使用modelMapper创建一个新对象,不需要额外的配置。 但在将dto映射到实体对象后,实体对象上的性别为空。 对象有性别,我已经检查了很多。 请帮我理解这个问题。

  • 问题内容: 我需要预先将没有实现接口的枚举映射到现有数据库,该数据库使用将该枚举存储在与所有者类相同的表中。 在这种情况下应如何处理映射?持久化到数据库不会改变,因为实现该接口的所有枚举都将具有不同的值,但是我不确定应如何从数据库中检索对象(我是否需要自定义映射器,它将尝试实例化一个使用指定的enum类进行枚举吗?Hibernate是否本身支持此功能?)。 问题答案: 可以创建一个自定义(例如th

  • 问题内容: Hibernate提供的注释支持使用或两种类型的映射。当我们使用映射时,它使用的“名称” 而不是Enum 的表示形式。在数据库列仅包含一个字符的情况下,这是一个问题。例如,我有以下枚举: 当我坚持枚举使用,即休眠尝试在数据库中存储的值是开放的。但是,我的数据库列仅包含一个字符,因此会引发异常。 克服这个问题的一个办法是改变枚举类型持有单个字符(如,代替,)。但是,这降低了可读性。有什么