Java 枚舉那點事

目錄數據庫

最近有需求,想存自定義的枚舉值,好比ide

HOTLINE("Hotline")

我想存 Hotline 因而研究了一下Java的枚舉問題this

以下數據庫的Entity (貧血模型哈)code

@Entity
@Table(name = "complaint")
public class Complaint {
    @Id
    @GeneratedValue
    private Long id;

    private CaseOrigin origin;
}

枚舉orm

public enum CaseOrigin {
    HOTLINE("Hotline"),
    EMAIL("mail/fax/email"),
    WALK_IN("Walk-in"),
    OTHER("Others");
 
    public String value() {
        return value;
    }
    
    private final String value;
    
    private CaseOrigin(String value) {
        this.value = value;
    }
}

用的是Spring Boot 自帶的 Hibernate
Hibernate 提供了兩種方便的註解接口

  • 1 也就是默認的註解 ,存是的 1,2,3,4,5 之類的數字
@Enumerated(EnumType.ORDINAL)
    private CaseOrigin origin;
  • 2 這是存枚舉的name 如 : OTHER("Others") 存的是OTHER
@Enumerated(EnumType.STRING)
    private CaseOrigin origin;

可是這兩種方式,都不符合個人需求,我想存的是 Others
因而,找到了目前爲止最優雅的方式get

實現接口 AttributeConverter 重寫接口的方法,很表意,就不解釋了。it

public class CaseOriginConverter implements AttributeConverter<CaseOrigin, String> {
    
    @Override
    public String convertToDatabaseColumn(CaseOrigin attribute) {
        return attribute.value();
    }
    
    @Override
    public CaseOrigin convertToEntityAttribute(String dbData) {
      return CaseOrigin.formDbValue(dbData);
    }
}

枚舉咱們也要改造一下,固然,若是不想改造枚舉類。在類CaseOriginConverter 重寫convertToEntityAttribute(String dbData) 就要費點事了,好比switch,反射(最優雅的方式 )form

public enum CaseOrigin {
    HOTLINE("Hotline"),
    EMAIL("mail/fax/email"),
    WALK_IN("Walk-in"),
    OTHER("Others");
    
    
    public String value() {
        return value;
    }
    
    private final String value;
    
    public static final Map<String, CaseOrigin> dbValues = new HashMap<>();
    
    static {
        for (CaseOrigin value : values()) {
            dbValues.put(value.value, value);
        }
    }
    
    private CaseOrigin(String value) {
        this.value = value;
    }
    
    public static CaseOrigin formDbValue(String dbValue) {
        return dbValues.get(dbValue);
    }
}

最後用的地方到了class

@Convert(converter = CaseOriginConverter.class)
    private CaseOrigin origin;

這樣就OK了。

相關文章
相關標籤/搜索