【发布时间】:2023-03-03 06:30:20
【问题描述】:
我目前正在尝试学习 hibernate,遇到了一个从 OOP 和 DB 角度来看都合理的问题,但我无法找到解决方案。
我的 java 部分或多或少是这样的:
@Entity
@Table (name = "Vehicles")
class Vehicle {
@Id
@Column (name = "UUID")
UUID id;
VehicleType type
(getters, setters, other values, etc.)
}
enum VehicleType {
TRUCK,
TRAILER,
OTHER;
}
我的数据库部分有两个表 - 一个用于车辆,一个用于车辆类型的查找表:
车辆
UUID VARCHAR (PK)
vehicle_type_id INT (FK to VehicleTypes)
车辆类型
vehicle_type_id INT (PK)
vehicle_type VARCHAR
我的问题是,是否可以按照所介绍的方式进行安排?如果可能,如何实现它(注释等)。如果没有,实现类似结构的最佳方法是什么?
-----编辑-----
使用 Anthony Patricio 描述的 solution,我已经成功实现了我的目标(或多或少)。
DB 部分保持不变,而 Java 部分如下所示:
@Entity
@Table (name = "Vehicles")
class Vehicle {
@Id
@Column (name = "UUID")
UUID id;
@Column (name = "vehicle_type_id")
@Type (type = "VehicleEnumUserType")
VehicleType type
(getters, setters, other values, etc.)
}
enum VehicleType {
TRUCK(1),
TRAILER(2),
OTHER(0);
private int value;
VehicleType(int value){
this.value = value;
}
public int getValue() {
return value;
}
public static VehicleType fromValue(int value){
for (VehicleType type : VehicleType.values()){
if (value == type.value) return type;
}
throw new IllegalArgumentException("Value not mapped by VehicleType enum");
}
}
VehicleEnumUserType implements UserType{
private static final int[] SQL_TYPES = {Types.INTEGER};
public Object nullSafeGet(ResultSet resultSet, String[] strings, SharedSessionContractImplementor sharedSessionContractImplementor, Object o)
throws HibernateException, SQLException {
int number = resultSet.getInt(strings[0]);
return resultSet.wasNull() ? null : VehicleType.fromValue(number);
}
public void nullSafeSet(PreparedStatement preparedStatement, Object o, int i, SharedSessionContractImplementor sharedSessionContractImplementor)
throws HibernateException, SQLException {
if (o == null){
preparedStatement.setNull(i, Types.INTEGER);
} else {
preparedStatement.setInt(i, ((VehicleType)o).getValue());
}
}
// other mandatory methods required by UserType interface
}
此解决方案符合我的要求 - 车辆类型在 DB 端(通过查找表限制)和 Java 端(通过 VehicleType 枚举)都受到限制。此外,车辆类型以整数形式存储,减少了存储数据所需的空间。最后但同样重要的是,此解决方案允许非常安全地添加新车辆类型(例如与 EnumType.ORDINAL 相关的问题)。
希望任何人都觉得这个解决方案有用。
【问题讨论】:
标签: hibernate enums lookup-tables