我想我也想尝试一下我的蛋糕并在这里吃,但我们会看看我能找到合理的解决方案。我有一个Spring Boot / JPA / Hibernate应用程序,它将与MySQL作为其后备存储。我有几种情况,从OOP的角度来看,我的实体类形成了父/子层次结构,如下所示:
// Groovy pseudo-code!
class Vehicle {
Long id
Long maxSpeed
String make
String model
}
class Motorcycle extends Vehicle {
Boolean isTwoStroke
}
class Car extends Vehicle {
Boolean hasLeatherInterior
}
等。通常,在JPA之外,我可能会像这样设计各自的表:
CREATE TABLE motorcycles (
motorcycle_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
motorcycle_max_speed BIGINT UNSIGNED,
motorcycle_make VARCHAR(50) NOT NULL,
motorcycle_model VARCHAR(50) NOT NULL,
motorcycle_is_two_speed BIT NOT NULL,
# PK, FK, UC, index constraints down here (omitted for brevity)
);
CREATE TABLE cars (
car_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
car_max_speed BIGINT UNSIGNED,
car_make VARCHAR(50) NOT NULL,
car_model VARCHAR(50) NOT NULL,
car_has_leather_interior BIT NOT NULL,
# PK, FK, UC, index constraints down here (omitted for brevity)
);
理想情况我希望将此表设计保持原样,并使用"父车辆的名称"列完全像我上面那样。但是,如果我正确地理解了Hibernate / JPA API,那么我就不会在没有做出某种牺牲的情况下认为它的可能性。我想我要么在app层牺牲继承,这样我就可以像在DB中一样命名子类中的列:
@Entity
class Motorcycle { // No longer extends Vehicle :-(
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name = "motorcycle_id")
Long id
@Column(name = "motorcycle_max_speed")
Long maxSpeed
@Column(name = "motorcycle_make")
String make
@Column(name = "motorcycle_model")
String model
@Column(name = "motorcycle_is_two_speed")
Boolean isTwoStroke
}
@Entity
class Car { // No longer extends Vehicle :-(
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name = "car_id")
Long id
@Column(name = "car_max_speed")
Long maxSpeed
@Column(name = "car_make")
String make
@Column(name = "car_model")
String model
@Column(name = "car_has_leather_interior")
Boolean hasLeatherInterior
}
或我认为我可以保留app-layer继承,但之后需要像我这样重构我的数据库表:
CREATE TABLE motorcycles (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
max_speed BIGINT UNSIGNED,
make VARCHAR(50) NOT NULL,
model VARCHAR(50) NOT NULL,
motorcycle_is_two_speed BIT NOT NULL,
# PK, FK, UC, index constraints down here (omitted for brevity)
);
CREATE TABLE cars (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
max_speed BIGINT UNSIGNED,
make VARCHAR(50) NOT NULL,
model VARCHAR(50) NOT NULL,
car_has_leather_interior BIT NOT NULL,
# PK, FK, UC, index constraints down here (omitted for brevity)
);
所以我问:是否可以保留我的应用层继承(让Motorcycle
和Car
继承Vehicle
)和使用我的首选约定命名我的数据库表列?
答案 0 :(得分:1)
可以使用@MappedSuperclass(Designates a class whose mapping information is applied to the entities that inherit from it. A mapped superclass
has no separate table defined for it.
)
车辆类:
@MappedSuperclass
public class Vehicle {
@Id
@GeneratedValue
Long id;
Long maxSpeed;
String make;
String model;
}
摩托车子类
@Entity
@AttributeOverrides({
@AttributeOverride(name = "id", column = @Column(name = "motorcycle_id"))
})
public class Motorcycle extends Vehicle {
Boolean isTwoStroke;
}