gpt4 book ai didi

java - 按类型表映射子类(多对一 Hibernate)

转载 作者:行者123 更新时间:2023-11-30 03:56:38 26 4
gpt4 key购买 nike

我必须制作拼贴项目的域层。我们的标准很少,比如我们必须使用 Hibernate,而且数据库也是固定的。

数据库的相关部分看起来几乎像这样:

BusEntity(表 1)

  • 总线 ID
  • 公交车具体信息

总线类型(表 2)

  • 总线类型 ID
  • 席位
  • ...
  • 子类鉴别器

我遇到的问题是域层中有两种类型的总线通过总线类型表中的鉴别器进行区分:

@Entity
class Bus
{
@Id
int _id;
...
}

@Entity
class BusSubClass1 extends Bus
{
...
}

@Entity
class BusSubClass2 extends Bus
{
...
}

有没有办法用 Hibernate 和 JPA 映射类似的东西?感谢您的每一个回答。

约亨·莫伦特

最佳答案

是的,映射这种场景的方法很少。 JPA 提供对三种不同数据表示形式的支持:

  • 单表策略
  • 加入策略
  • 每类表策略

换句话说,根据所使用的继承类型,您将获得不同的数据库模型。各种 JPA 提供程序可能支持其他继承策略。

考虑以下示例:

@Entity
@Inheritance //by default SINGLE_TABLE strategy
@DiscriminatorColumn( //not supported for TABLE_PER_CLASS strategy
name = "BUS_TYPE",
discriminatorType = DiscriminatorType.INTEGER
)
public abstract class Bus {
@Id
protected int id;
protected int seats;

public Bus() {
}
}

@Entity
@DiscriminatorValue(value = "1") //not supported for TABLE_PER_CLASS strategy
public class BusSubClass1 extends Bus {
private String specific1;

public BusSubClass1() {
}
}

@Entity
@DiscriminatorValue(value = "2") //not supported for TABLE_PER_CLASS strategy
public class BusSubClass2 extends Bus {
@Temporal
private Data specific2;

public BusSubClass2() {
}
}
<小时/>

使用 InheritanceType.SINGLE_TABLE 策略会生成包含所有具体实体类型的单个数据库表:

 Bus

ID BUS_TYPE SEATS SPECIFIC1 SPECIFIC2
-- -------- ----- --------- ---------
1 1 50 qwerty
2 1 55 asdfgh
3 2 30 2014-01-01
  • 继承层次结构中的每个具体实体实例都通过鉴别器值(此处由 BUS_TYPE 列指示)来区分
  • 所有数据库列都必须声明为可空,因为并非所有列都可能包含值(因此对于不能设置为空的列可能会出现问题)
  • 层次结构的宽或深可能会影响性能(表中分别存在大量冗余列或行)
  • 缺乏规范化可能会浪费数据库表中的空间
  • 为读写操作提供良好的性能(多态查询不需要连接,只需要鉴别器值)
  • 添加/删除实体字段可能会出现问题(从数据库管理的角度来看)
<小时/>

使用 InheritanceType.JOINED 策略会导致每个实体类型有多个数据库表(Bus 中的所有共享字段都存储在相应的表中):

 Bus                        BusSubClass1          BusSubClass2

ID BUS_TYPE SEATS ID SPECIFIC1 ID SPECIFIC2
-- -------- ----- -- --------- -- ---------
1 1 50 1 qwerty 3 2014-01-01
2 1 55 2 asdfgh
3 2 30
  • 继承层次结构中的每个具体实体类都通过鉴别器值(此处由 BUS_TYPE 列指示)来区分
  • 规范化改进了数据存储(与 SINGLE_TABLE 策略相比,未使用的空间更少)
  • 非多态查询(针对单个具体实体)需要联接
  • 多态查询(针对实体类的宽或深层次结构)需要多个联接,并且可能成本高昂
  • 添加/删除实体字段相当简单(从数据库管理的角度来看)
<小时/>

使用 InheritanceType.TABLE_PER_CLASS 策略会导致每个实体类型只有一个数据库表(Bus 中的所有共享字段都在具体子类中重新定义):

 BusSubClass1                BusSubClass2

ID SEATS SPECIFIC1 ID SEATS SPECIFIC2
-- ----- --------- -- ----- ---------
1 50 qwerty 3 30 2014-01-01
2 55 asdfgh
  • 继承层次结构中的每个具体实体类仅通过共享标识符来区分(不使用鉴别​​器)
  • 规范化改进了数据存储(与 SINGLE_TABLE 策略相比,未使用的空间更少,但比 JOINED 策略的情况更多)
  • 非多态查询(针对单个具体实体)非常高效,因为不需要连接
  • 多态查询(针对实体类的宽或深层次结构)需要多个联接,并且可能成本高昂
  • 添加/删除实体字段非常简单(从数据库管理的角度来看)

关于java - 按类型表映射子类(多对一 Hibernate),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23011672/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com