是否可以将Enums用作自定义JPA实体中的字段(列)类型?这是一个例子:
@Getter @Setter
@Entity
@Table(name = "payments")
public class PaymentEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "status")
private Integer statusId;
public PaymentStatuses getStatus() {
return PaymentStatuses.valueOf(statusId);
}
public PaymentEntity setStatus(PaymentStatuses status) {
statusId = status == null ? null : status.getId();
return this;
}
}
public enum PaymentStatuses {
CREATED(1),
COMPLETED(2),
CANCELED(3);
private Integer id;
private PaymentStatuses(Integer id) {
this.id = id;
}
public Integer getId() {
return id;
}
public static PaymentStatuses valueOf(Integer id) {
for (PaymentStatuses value : values())
if (value.getId().equals(id))
return value;
return null;
}
}
上面的代码运行正常,但使用statusId
和getStatus
setStatus
的方法看起来很丑陋。
我想在我的实体中使用PaymentStatuses
作为字段的类型。像这样:
@Getter @Setter
@Entity
@Table(name = "payments")
public class PaymentEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "status")
private PaymentStatuses status;
}
请告诉我,是否有可能?
答案 0 :(得分:4)
使用@Enumerated(EnumType.ORDINAL)
无效,因为ORDINAL
模式开始为0
因此,枚举的3个第一个值将在带有0
,1
和2
值的数据库中表示。
枚举中代表它的枚举中的id
字段从1
变为3
:
CREATED(1),
COMPLETED(2),
CANCELED(3);
此外,这种方式会将枚举中定义的元素的顺序与在数据库中表示它们的方式相关联。这可能会在将来添加/删除枚举值,这不是一件好事。
解决问题的更好方法是定义javax.persistence.AttributeConverter
并将其与@Convert
一起使用
因此,创建一个AttributeConverter
实现来指示如何从DB转换为枚举,将枚举转换为DB。
然后在您的实体中声明PaymentStatuses status
,并通过指定@Convert
实施类,使用AttributeConverter
对其进行注释。
@Getter @Setter
@Entity
@Table(name = "payments")
public class PaymentEntity {
...
@Convert(converter = PaymentStatusesConverter.class)
private PaymentStatuses status;
...
}
public class PaymentStatusesConverter implements AttributeConverter<PaymentStatuses, Integer> {
@Override
public Integer convertToDatabaseColumn(PaymentStatuses status) {
return status.getId();
}
@Override
public PaymentStatuses convertToEntityAttribute(Integer status) {
return PaymentStatuses.valueOf(status);
}
}
答案 1 :(得分:1)
是的,但是当您保存到数据库时,它将保留枚举值的当前索引(在您的情况下为0表示CREATED,1表示COMPLETED等),如果您更改枚举值,这将给您带来麻烦。为避免这种情况,您可以使用@Enumerated
注释,如:
@Getter @Setter
@Entity
@Table(name = "payments")
public class PaymentEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "status")
@Enumerated(EnumType.ORDINAL) // There is also EnumType.STRING, or you can define a custom EnumType
private PaymentStatuses status;
}
答案 2 :(得分:0)
如果您希望将数据存储在数据库中,可以使用bool
,例如Java枚举名称的名称(@Enumerated(EnumType.STRING)
)