gpt4 book ai didi

mysql : why would I require AttributeConverter over enum to map a DB column having enum datatype as enum with a JPA entity?

转载 作者:行者123 更新时间:2023-11-29 06:42:15 28 4
gpt4 key购买 nike

我有一个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 的文章但由于我的枚举中的值非常有限并且修改的机会较小,因此我无法将所有这些文章与我的要求联系起来。

我的设计有什么遗漏或者可以改进的地方吗?

我扔掉的文章:
vladmihalcea
thorban以及其他一些 stackoverflow 问题。

更新:阅读 Jens 的答案后,我决定实现 AttributeConverter(针对用户的性别)。这让我有点困惑:
为什么我决定使用枚举作为 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 是邪恶的,因为有一天如果我需要向枚举列添加额外的值,这将需要表 ALTER,但情况不是一样吗使用AttributeConverter?因为我们还使用了 java enum,如果有一天需要新的性别,则需要更改它?
2.如果我使用AttributeConverter,我必须在某处记录javaenum(这里UserGender)解释,以便DBA能够理解什么是F,M ,O 代表。我在这儿吗?

最佳答案

这些文章为您提供了丰富的潜在缺点选择:

使用@Enumerated(EnumType.STRING)具有以下内容:

  • 与其他选项相比,它占用大量空间。请注意,这意味着需要加载和通过线路传输更多数据,这也会对性能产生影响。我们不知道这对您来说是否是一个问题,并且在进行一些性能测试之前您也不会知道。
  • 将枚举值的名称与列值紧密联系起来。这可能存在风险,因为开发人员习惯于快速重命名内容,并且您需要使用实际的遗留数据进行测试才能发现这一点。

如果您不处理大量数据,而更新所有行的列是一个实际问题,那么我不会担心。当简单的解决方案实际上成为问题时,引入 AttributeConverter 并更新数据是很容易的。

有关更新问题的更新:

  1. 我不相信任何东西都是“邪恶的”,因为它可能需要 ALTER TABLE 语句。根据这个论点,我们应该完全废除关系数据库,因为使用它们需要 DDL,并且应用程序的发展将需要更多 DDL。当然,DDL 语句的必要性使得部署变得更加复杂。但无论如何你都需要能够处理这件事。

    但是,在这种情况下,使用 AttributeConverter 确实不需要任何 DDL,因为您只需将另一个值放入同一列中,该列没有任何特殊约束,除了值的最大长度。这假设您没有对该列进行检查约束来限制合法值。

    1. 您是否必须记录 Enum 与数据库中存储的值之间的关系?取决于你的团队。 DBA 关心数据的含义吗? DBA 是否有能力理解 Java 代码?如果 DBA 需要或想要知道但不能或不会从源代码中获取信息,则必须将其记录下来。确实如此。

关于mysql : why would I require AttributeConverter over enum to map a DB column having enum datatype as enum with a JPA entity?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51065625/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com