zoukankan      html  css  js  c++  java
  • 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); } }
  • 相关阅读:
    动态与静态Include
    java回收算法
    reflection是如何工作的。
    hashcode和equals的约定关系如下
    Java调试器
    混合赋值运算符的使用
    Spring
    Math.?
    oracle--触发器(转)
    oracle --游标详解(转)
  • 原文地址:https://www.cnblogs.com/hankuikui/p/11430141.html
Copyright © 2011-2022 走看看