描述

上述每种策略和技术都有其自身的优点和缺点。选择特定策略的一般建议如下所示:

基于 UNION 的 TABLE_PER_CLASS 策略

如果不需要多态查询和关联,则最好选择此策略。如果您很少做(或根本不做)“从用户用户中选择用户”。如果您没有任何引用用户的实体类,这是最好的选择(因为您仍然可以添加优化的多态查询和关联)。

SINGLE_TABLE 策略

应使用此策略:

a) 仅适用于简单任务。在规范化和 NOT NULL 约束至关重要的情况下,应该首选策略 #3 (JOINED)。思考在这种情况下是否不值得完全放弃继承而代之以委托是有道理的。

b) 如果需要多态查询和关联,以及在运行时动态定义具体类。同时,子类声明的新字段相对较少,与超类的主要区别在于行为。

最重要的是,您与 DBA 进行了认真的对话。

加盟战略

这种策略在速度和约束方面是最有效的。适用于需要多态查询和关联,但子类声明新字段较多的情况。

这里需要注意的是:JOINED 和 TABLE_PER_CLASS 之间的决定需要对真实数据的查询执行计划进行评估,因为继承层次结构的宽度和深度会使连接成本(以及性能)变得无法接受。

另外,值得考虑的是,继承注解不能应用于接口。

明确的

还可能存在这样一种情况,即您在数据库中具有实体类层次结构和共享存储策略。但是无论出于何种原因,您都不希望在对基类进行查询时返回某个层次结构类。

有一个注释:

@Polymorphism(type = PolymorphismType.EXPLICIT)

如果我们将它添加到Client类:

@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@Entity
class User {
  int id;
  String name;
  LocalDate birthday;
}
@Entity
class Employee extends User {
 	String occupation;
 	int salary;
 	LocalDate join;
}
@Entity
@Polymorphism(type = PolymorphismType.EXPLICIT)
class Client extends User {
   String address;
}

那么HQL查询在查询基类时会忽略这个类的对象:

List<User> accounts = session.createQuery("from User").getResultList();

此查询将返回UserEmployee对象的列表,但不返回Client