在 Hibernate 中,处理枚举类型的映射有几种方式,主要依赖于 @Enumerated
注解来指定枚举值如何保存到数据库。以下是常见的做法:
1. 使用 @Enumerated(EnumType.STRING)
这是推荐方式,将枚举的名字(字符串)保存到数据库中,可读性好,不容易出错。
public enum Status {
ACTIVE, INACTIVE, DELETED
}
@Entity
public class User {
@Id
private Long id;
@Enumerated(EnumType.STRING)
private Status status;
// getters and setters
}
数据库中存储: ACTIVE
, INACTIVE
等字符串。
2. 使用 @Enumerated(EnumType.ORDINAL)
默认方式,保存的是枚举的序号(ordinal),不推荐,因为如果枚举顺序变化会导致数据错乱。
@Enumerated(EnumType.ORDINAL)
private Status status;
数据库中存储: 0
, 1
, 2
,表示枚举的索引。
3. 自定义枚举类型转换(使用 @Converter
)
更灵活的方式,适合枚举需要映射成自定义值,比如数据库中用 A
, I
, D
表示状态。
public enum Status {
ACTIVE("A"), INACTIVE("I"), DELETED("D");
private String code;
Status(String code) {
this.code = code;
}
public String getCode() {
return code;
}
public static Status fromCode(String code) {
for (Status s : Status.values()) {
if (s.getCode().equals(code)) {
return s;
}
}
throw new IllegalArgumentException("Unknown code: " + code);
}
}
转换器:
@Converter(autoApply = true)
public class StatusConverter implements AttributeConverter<Status, String> {
@Override
public String convertToDatabaseColumn(Status status) {
return status != null ? status.getCode() : null;
}
@Override
public Status convertToEntityAttribute(String dbData) {
return dbData != null ? Status.fromCode(dbData) : null;
}
}
总结建议:
方法 | 优点 | 缺点 |
---|---|---|
EnumType.STRING | 可读性好、安全 | 占用存储空间略大 |
EnumType.ORDINAL | 存储节省 | 不稳定,容易出错 |
@Converter 自定义转换器 | 可灵活映射任意值 | 需要多写一点代码 |