我正在吃晚饭 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;
我将其Map到相应的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
}
我想知道使用这种方法在持久层实现db enum有什么缺点吗?我抛出了多篇文章,其中建议使用attributeconverter,但由于我的枚举中的值非常有限,修改的机会较少,我无法将所有这些文章与我的要求联系起来。
我的设计中是否有遗漏或改进之处?
我扔的文章:
弗拉德米哈尔恰
索班和其他一些问题。
更新:在阅读了jens的答案之后,我决定实施 AttributeConverter
(供用户参考) gender
). 这让我有点困惑:
为什么我决定使用enum作为mysql列类型:因为它限制了值并且需要更少的空间。因为mysql在场景后面存储枚举的序数值,当被要求提供值时,它表示枚举的字符串值,所以它节省了空间。
我对性别的理解:
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
在db中是邪恶的,因为如果有一天我需要向enum列添加额外的值,这将需要一个表alter,但是使用 AttributeConverter
? 因为我们也使用 java enum
如果有一天需要新的性别,哪一个需要改变?
2如果我使用 AttributeConverter
,我将不得不记录java enum
( UserGender
这里)解释某处,以便dba能够理解f,m,o代表什么。我就在这里吗?
1条答案
按热度按时间t30tvxxf1#
这些文章为您提供了丰富的潜在缺点选择:
使用
@Enumerated(EnumType.STRING)
具有以下特性:与其他选项相比,它占用了大量空间。请注意,这意味着需要通过导线加载和传输更多数据这也会影响性能。我们不知道这是否是一个问题,你也不会知道,直到你做了一些性能测试。
将枚举值的名称硬绑定到列值。这可能是有风险的,因为开发人员习惯于快速重命名东西,而且您需要使用实际遗留数据进行测试才能捕捉到这一点。
如果您不处理大量的数据,而更新所有行的列是一个实际的问题,我就不会担心了。引入一个
AttributeConverter
当简单的解决方案变成问题时更新数据。关于更新问题的更新:
我不相信任何事情都是“邪恶”的说法,因为它可能需要
ALTER TABLE
声明。根据这个论点,我们应该完全废除关系数据库,因为使用它们需要ddl,而应用程序的演化将需要更多的ddl。当然,ddl语句的必要性使得部署更加复杂。但你无论如何都要有能力处理这件事。但事实上
AttributeConverter
在这种情况下,您不需要任何ddl,因为您只需将另一个值放在同一列中,除了该值的最大长度之外,该列没有任何特殊约束。这假设您对列没有限制合法值的check约束。你必须记录
Enum
以及数据库中存储的值?取决于你的团队。dba是否关心数据的含义?dba是否有访问权限和理解java代码的技能?如果dba需要或者想要知道,但是不能或者不想从源代码中获取信息,那么您必须对其进行文档化。是的。