[英]mysql : why would I require AttributeConverter over enum to map a DB column having enum datatype as enum with a JPA entity?
我有一個user
數據庫表為:
CREATE TABLE IF NOT EXISTS `user` (
`user_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`first_ name` VARCHAR(45) NOT NULL,
`active_status` ENUM('ACTIVE', 'PENDING', 'DEACTIVATED', 'BLOCKED', 'SPAM', 'DELETED') NOT NULL ,
UNIQUE INDEX `unique_id_UNIQUE` (`unique_id` ASC),
UNIQUE INDEX `email_UNIQUE` (`email` ASC),
PRIMARY KEY (`user_id`))
ENGINE = InnoDB;
我將其映射為相應的JPA實體類,如下所示:
@Entity
public class User implements OfloyEntity {
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "user_id", unique = true, nullable = false)
private int userId;
//other fields
@Enumerated(EnumType.STRING)
@Column(name = "active_status", nullable = false, length = 11)
private UserStatus activeStatus;
如您所見,我已經將activeStatus
映射到一個enum UserStatus
以限制持久層本身的整體。
public enum UserStatus {
ACTIVE,
PENDING,
DEACTIVATED,
BLOCKED,
DELETED,
SPAM
}
我想知道使用這種方法在持久層中實現數據庫枚舉是否有任何缺點? 我扔了多篇推薦使用AttributeConverter的文章,但是由於枚舉中的值非常有限且修改的機會較小,因此我無法將所有這些文章與我的要求聯系起來。
是否有我缺少的東西,或者可以對我的設計進行任何改進?
我丟的文章:
紫杉
thorban和其他一些stackoverflow問題。
更新 :閱讀Jens的答案后,我決定實現AttributeConverter
(針對用戶的gender
)。 這讓我有些困惑:
為什么我決定使用enum作為MYSQL列類型 :因為它限制了值並需要較少的空間。 因為MYSQL將其枚舉的序數值存儲在幕后,並且當要求提供它的String值時,它節省了空間。
我對性別的實現:
public enum UserGender {
MALE('M'),
FEMALE('F'),
OTHER('O');
private Character shortName;
private UserGender(Character shortName) {
this.shortName = shortName;
}
public Character getShortName() {
return shortName;
}
public static UserGender fromShortName(Character shortName) {
switch (shortName) {
case 'M': return UserGender.MALE;
case 'F' : return UserGender.FEMALE;
case 'O' : return UserGender.OTHER;
default:
throw new UserGenderNotSupportedException("user gender with shortName : " + shortName + " not supported");
}
}
}
轉換器類別:
@Converter(autoApply = true)
public class UserGenderConverter implements AttributeConverter<UserGender, Character> {
@Override
public Character convertToDatabaseColumn(UserGender userGender) {
return userGender.getShortName();
}
@Override
public UserGender convertToEntityAttribute(Character dbGender) {
return UserGender.fromShortName(dbGender);
}
}
現在,主要的疑問 :
1.根據博客,在數據庫中使用MYSQL enum
是邪惡的,因為總有一天,如果我需要向枚舉列添加額外的值,這將需要一個表ALTER,但使用AttributeConverter
情況不一樣嗎? 因為這里也使用了java enum
,如果有朝一日需要新的性別,那將需要更改?
2.如果使用AttributeConverter
,則必須在某個地方記錄Java enum
(此處為UserGender
)說明,以便DBA可以理解F,M,O代表什么。 我在這里嗎?
這些文章為您提供了許多潛在的弊端:
使用@Enumerated(EnumType.STRING)
具有以下內容:
如果您不使用真正大量的數據來更新所有行的列,這是一個實際的問題,那我就不會費心。 當簡單的解決方案實際上成為問題時,引入AttributeConverter
並更新數據就很容易了。
我不認為任何東西都是“邪惡的”,因為它可能需要ALTER TABLE
語句。 通過這種說法,我們應該完全廢除關系數據庫,因為使用關系數據庫需要DDL,而應用程序的演進將需要更多的關系數據庫。 當然,DDL語句的必要性使部署更加復雜。 但是無論如何,您都需要能夠處理此問題。
但是的確,在這種情況下,使用AttributeConverter
不需要任何DDL,因為您只需要在同一列中放入另一個值即可,該值沒有任何特殊限制,但該值的最大長度除外。 假設您在該列上沒有檢查約束來限制合法值。
Enum
與數據庫中存儲的值之間的關系? 取決於您的團隊。 DBA甚至關心數據的含義嗎? DBA是否具有訪問權限和掌握Java代碼的技能? 如果DBA需要或想要知道並且無法或不會從源代碼中獲取信息,則必須對其進行記錄。 真正。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.