枚舉類型在JPA中的使用
- 2020 年 12 月 1 日
- 筆記
- Spring Data JPA
首先介紹一篇很好的文章:Persisting Enums in JPA
一、枚舉類型的基礎知識
public enum Status { OPEN, REVIEW, APPROVED, REJECTED; }
1、枚舉序號:
OPEN, REVIEW, APPROVED, REJECTED 枚舉的序號從0開始依次遞增,本例中分別為0、1、2、3,可以通過Enum.ordinal()獲取;
缺點:
- 可讀性,閱讀int類型的數據庫紀錄很困難;
- 順序性,無法自定義序號(枚舉序號從0遞增步進為1),在保存某些行業的標準代碼(如HTTP狀態碼)頗為不便;
- 健壯性,如果錯誤地在中間插入或者重排序,會導致數據異常且不易發現;
優點:
- 節省存儲空間
2、枚舉字面值:
OPEN, REVIEW, APPROVED, REJECTED 枚舉的字面值即為名稱本身,本例中分別為 OPEN、REVIEW、APPROVED、REJECTED,可以通過Enum.name()獲取;
缺點:
- String類型,佔用空間更大,
- 不支持數字,不支持重命名,
- 不推薦使用NON-ASCII字符,而很多情況下我們有保存中文的需求;
- 無法兼容以「枚舉序號」保存的歷史項目;
優點:
- 可以通過@Enumerated(EnumType.STRING)比較方便地進行轉化處理
3、枚舉屬性值:
// 我們可以通過如下方法定義枚舉的屬性值 public enum Gender { BOY(0, "boy", "Boy"), GIRL(1, "girl", "Girl"); private int value; private String format1; private String format2; //....省略 }
缺點:
- 枚舉屬性值和枚舉序號之間要保證區分度,防止混淆和存儲是發生錯誤操作;
優點:
- 自由,靈活;
二、枚舉的存儲
1、存儲枚舉序號和枚舉字面值的存儲
1.1 使用@Enumerated註解
- 在存儲枚舉時,JPA默認保存 枚舉序號;
- 在序列化枚舉時,JPA默認顯示 枚舉字面值;
- 可以通過@Enumerated註解切換枚舉存儲時實際保存的行為
- @Enumerated(EnumType.ORDINAL) – 存儲序號
- @Enumerated(EnumType.STRING) – 存儲字面值
- 可以通過在枚舉屬性上添加@JsonValue註解作為序列化的值;
1.2 使用@PostLoad和@PrePersist
不推薦,會使JPQL失效,還會增加@Transient字段
2、存儲枚舉屬性值
如果需要存儲枚舉屬性值,可以使用@Converter註解
三、參考資料
1、JPA插入枚舉類型字段(介紹了枚舉的序號/字面值/屬性)
2、Persisting Enums in JPA(介紹了如何使用@Enumerated、@PostLoad和@PrePersist、@Converter進行枚舉的存儲)
3、解決JPA的枚舉局限性(介紹了實現中的一些問題)