spring boot 枚举使用的坑3

上一篇说到spring boot 使用jackson在枚举enum序列化和反序列化的问题,

再来说说在JPA中实体entity使用枚举的问题。

还是这个枚举:

@Getter
@AllArgsConstructor
public enum  EnumExpenseType implements BaseEnum {
    小欢喜(1),
    大欢喜(2);

    private final int value;
}

当然,如果value值和枚举的索引ordinal能够对应上,就不用做任务配置了,这里的前提是没有对应上。

无论是在实体的保存和查询映射上还是有和jackson序列化同样的问题,毕竟jpa是不知道我们的枚举的构造函数是什么的,除非我们告诉它。

直接上代码:

@Slf4j
public class EnumConverter<E extends BaseEnum> implements AttributeConverter<E, Integer> {

    private final Class<E> clazz;

    public EnumConverter(Class<E> clazz) {
        this.clazz = clazz;
    }

    @Override
    public Integer convertToDatabaseColumn(BaseEnum attribute) {
        return attribute.getValue();
    }

    @SuppressWarnings("unchecked")
    @Override
    public E convertToEntityAttribute(Integer dbData) {
        if (dbData == null) {
            return null;
        }
        E[] enumConstants = clazz.getEnumConstants();
        for (E e : enumConstants) {
            if (e.getValue() == Integer.valueOf(dbData)) {
                return e;
            }
        }
        log.error("枚举转化异常。枚举【" + clazz.getSimpleName() + "】,数据库库中的值为:【" + dbData + "】");
        return null;
    }
}

这里关键的两个方法,一个是把枚举的值保存到数据时,使用我们定义的value,而不是索引ordinal。

另一个是从数据库中查询字段映射枚举时,按照value映射,而不是索引ordinal。

这只是一个抽象的方法,具体每个枚举还是再写一个类继承这个类,就可以了。

如:

public class EnumExpenseTypeConverter extends EnumConverter<EnumExpenseType> {
    public EnumExpenseTypeConverter () 
{
super(EnumExpenseType.class); } }
原文地址:https://www.cnblogs.com/hankuikui/p/11430141.html