描述

存储类层次结构的下一个方法是将层次结构中的所有类存储在一个表中。这种策略称为单表

例如,像这样:

CREATE TABLE user_ employee_client {
  id INT,
  name VARCHAR,
  birthday DATE,
  occupation VARCHAR,
  salary INT,
  join DATE,
  address VARCHAR,
  DTYPE VARCHAR
}

也就是说,我们有一个表,其中层次结构中所有类的列都用不同的颜色标记。还有一个特殊的服务列DTYPE VARCHAR,Hibernate 将在其中存储实体类的名称。

剩下唯一要做的就是向 Hibernate 解释 Entity 类的数据现在存储在数据库中的一张表中。这可以使用@Inheritance注释来完成:

@Inheritance(strategy = InheritanceType.SINGLE_TABLE)

我们班级的一个例子:

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

数据是如何存储的

现在让我们写一个例子,我们创建几个实体并将它们保存到数据库中:

Employee employee = new Employee();
employee.id = 101;
employee.name = "Ivanov";
employee.birthday = LocalDate.of("01-01-1999");
employee.occupation = "Programmer"
employee.salary = 100000;
employee.join = LocalDate.of("12-01-2018");
session.persist(employee);

Client client = new Client();
client.id = 102;
client.name = "Petrov";
client.birthday = LocalDate.of("15-11-1988");
client.address = "Shandara";
session.persist(client);

保存到数据库时,会执行如下SQL查询:

INSERT INTO user_ employee_client (id, name, birthday, occupation, salary, join, DTYPE)
VALUES (101, 'Ivanov', '01-01-1999', 'Programmer', 100000, '12-01-2018', 'Employee')

INSERT INTO user_ employee_client (id, name, birthday, address, DTYPE)
VALUES (102, 'Petrov', '15-11-1988', 'Shandara', 'Client')

将数据保存到表中时,Hibernate 仅传递它已知的实体字段。这意味着未指定的列将为 NULL。

这意味着您不能为职业列指定类型 NOT NULL,因为当一个客户存储在同一个表中时,他的职业将为 NULL。这是在同一个表中存储不同实体的缺点之一。

SQL 查询中的最后一个字段是 DTYPE 列,其中包含实体类的名称。当您想从表中读取数据时,Hibernate 会使用它。

例子:

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

此查询将返回存储在数据库中的所有用户类型对象的列表:User、Employee 和 Client。根据 DTYPE 列,将正确确定实体类型并创建正确类的对象。

在我们的例子中,帐户列表中将有两个对象:Employee 类型和 Client 类型。

HQL 规则。