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); } }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM