当对应的table有设定值时,在域模型(ORM)中使用Enum?
Use Enum in domain model (ORM) when the corresponding table has set values?
我有一个名为 job_class 的 table,它具有设置值:
这是 table 定义:
create table job_class (
job_class_code int NOT NULL PRIMARY KEY,
job_class_name varchar(50) NOT NULL,
ext_code varchar(10) NOT NULL
)
它总是有 3 行:
insert into job_class values (1, 'HOURLY', 'H')
insert into job_class values (2, 'SALARY', 'S')
insert into job_class values (3, 'EXECUTIVE', 'E')
job_class table 在 employee table 中被引用为 FK:
create table employee (
employee_id bigint NOT NULL PRIMARY KEY,
first_name varchar(50) NOT NULL,
middle_name varchar(50) NULL,
last_name varchar(50) NOT NULL,
job_class_code int NOT NULL FOREIGN KEY REFERENCES job_class (job_class_code)
)
现在要在域模型 (ORM) 中映射这个 table,通常我这样定义一个 class:
public class JobClass implements java.io.Serializable {
private Integer id;
private String name;
private String extCode;
public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getExtCode() { return extCode; }
public void setId(String extCode) { this.extCode = extCode; }
}
但是如果我将其定义为 Enum
会怎样:
public enum JobClass {
HOURLY(1,"HOURLY","H"),
SALARY(2,"SALARY","S"),
EXECUTIVE(3,"EXECUTIVE","E");
private Integer id;
private String name;
private String extCode;
private JobClass(Integer id, String name, String extCode) {
this.id = id;
this.name = name;
this.extCode = extCode;
}
public Integer getId() { return id; }
public String getName() { return name; }
public String getExtCode() { return extCode; }
}
在 ORM 中使用 Enum 有意义吗?在此之前,我从未在 ORM 中直接使用过 ENUM。在这种情况下这是一个好习惯吗?如果使用 Enum,Serializable 的含义是什么?
要使用枚举,您必须 100% 确定您的 table 不会有新记录或现有记录被更改,否则您会收到错误消息。
使用 ORM,您将能够通过 @Enumerated 注释映射到枚举,有多种方法可以做到:EnumType.ORDINAL 或 EnumType.STRING.
I'll let you check the documentation for the difference.
在您的情况下,由于您使用自动递增的 ID 作为 FK 键,因此使用 @Enumerated(EnumType.STRING)
并不好,因为它会强制您将枚举值命名为 1、2 和 3。
我不太喜欢使用 @Enumerated(EnumType.ORDINAL)
,因为它将您的枚举顺序与数据库 table 顺序联系在一起。但在你的情况下它会起作用。
如果您想走得更远,可以使用转换器 @Convert(converter = JobClassConverter.class)
您将保持枚举不变,员工的 jobClass 属性将如下所示:
@Column(name = "job_class_code")
@Convert(converter = JobClassConverter.class)
private JobClass jobClass;
然后您将创建 JobClassConverter
public class JobClassConverter implements AttributeConverter<JobClass, Integer> {
@Override
public Integer convertToDatabaseColumn(final JobClass pAttribute) {
if (pAttribute == null) {
return null;
} else {
switch (pAttribute) {
case HOURLY:
return 1;
case SALARY:
return 2;
case EXECUTIVE:
return 3;
}
}
}
@Override
public JobClass convertToEntityAttribute(final Integer pDbData) {
if (pDbData == null) {
return null;
} else {
switch (pDbData) {
case 1:
return JobClass.HOURLY;
case 2:
return JobClass.SALARY;
case 3:
return JobClass.EXECUTIVE;
}
}
}
}
我有一个名为 job_class 的 table,它具有设置值:
这是 table 定义:
create table job_class (
job_class_code int NOT NULL PRIMARY KEY,
job_class_name varchar(50) NOT NULL,
ext_code varchar(10) NOT NULL
)
它总是有 3 行:
insert into job_class values (1, 'HOURLY', 'H')
insert into job_class values (2, 'SALARY', 'S')
insert into job_class values (3, 'EXECUTIVE', 'E')
job_class table 在 employee table 中被引用为 FK:
create table employee (
employee_id bigint NOT NULL PRIMARY KEY,
first_name varchar(50) NOT NULL,
middle_name varchar(50) NULL,
last_name varchar(50) NOT NULL,
job_class_code int NOT NULL FOREIGN KEY REFERENCES job_class (job_class_code)
)
现在要在域模型 (ORM) 中映射这个 table,通常我这样定义一个 class:
public class JobClass implements java.io.Serializable {
private Integer id;
private String name;
private String extCode;
public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getExtCode() { return extCode; }
public void setId(String extCode) { this.extCode = extCode; }
}
但是如果我将其定义为 Enum
会怎样:
public enum JobClass {
HOURLY(1,"HOURLY","H"),
SALARY(2,"SALARY","S"),
EXECUTIVE(3,"EXECUTIVE","E");
private Integer id;
private String name;
private String extCode;
private JobClass(Integer id, String name, String extCode) {
this.id = id;
this.name = name;
this.extCode = extCode;
}
public Integer getId() { return id; }
public String getName() { return name; }
public String getExtCode() { return extCode; }
}
在 ORM 中使用 Enum 有意义吗?在此之前,我从未在 ORM 中直接使用过 ENUM。在这种情况下这是一个好习惯吗?如果使用 Enum,Serializable 的含义是什么?
要使用枚举,您必须 100% 确定您的 table 不会有新记录或现有记录被更改,否则您会收到错误消息。
使用 ORM,您将能够通过 @Enumerated 注释映射到枚举,有多种方法可以做到:EnumType.ORDINAL 或 EnumType.STRING.
I'll let you check the documentation for the difference.
在您的情况下,由于您使用自动递增的 ID 作为 FK 键,因此使用 @Enumerated(EnumType.STRING)
并不好,因为它会强制您将枚举值命名为 1、2 和 3。
我不太喜欢使用 @Enumerated(EnumType.ORDINAL)
,因为它将您的枚举顺序与数据库 table 顺序联系在一起。但在你的情况下它会起作用。
如果您想走得更远,可以使用转换器 @Convert(converter = JobClassConverter.class)
您将保持枚举不变,员工的 jobClass 属性将如下所示:
@Column(name = "job_class_code")
@Convert(converter = JobClassConverter.class)
private JobClass jobClass;
然后您将创建 JobClassConverter
public class JobClassConverter implements AttributeConverter<JobClass, Integer> {
@Override
public Integer convertToDatabaseColumn(final JobClass pAttribute) {
if (pAttribute == null) {
return null;
} else {
switch (pAttribute) {
case HOURLY:
return 1;
case SALARY:
return 2;
case EXECUTIVE:
return 3;
}
}
}
@Override
public JobClass convertToEntityAttribute(final Integer pDbData) {
if (pDbData == null) {
return null;
} else {
switch (pDbData) {
case 1:
return JobClass.HOURLY;
case 2:
return JobClass.SALARY;
case 3:
return JobClass.EXECUTIVE;
}
}
}
}