保护问题

今天我们将有一个新的超级有趣的方案——使用Hibernate特性将类层次结构保存到数据库中。

类层次结构是一组通过继承关系相互关联的类。

假设您要将三个类存储在数据库中:

class User {
  int id;
  String name;
  LocalDate birthday;
}
class Employee extends User {
 	String occupation;
 	int salary;
 	LocalDate join;
}
class Client extends User {
   String address;
}

类是相互继承的。最有趣的是,您想使用 Hibernate 来将这些类的对象存储在数据库中。

解决方案类型

Hibernate 有 4 种可能的方式可以将类层次结构与数据库中的表相关联:

  • 映射超类
  • 单表
  • 连接表
  • 每班表

每个策略在数据库中都采用自己的表结构。有时它们非常复杂。但是向他们查询 HQL 非常简单。这也正是Hibernate的优势体现的淋漓尽致的地方。

我从未听说过将这些术语翻译成俄语,所以我也建议用英语发音。

下面我们就来分析一下它们各自的意思。

@MappedSuperClass

让我们从最简单的解决方案开始——在数据库中,每个类都有单独的表。例如,这些:

CREATE TABLE user {
  id INT,
  name VARCHAR,
  birthday DATE
}
CREATE TABLE employee {
  id INT,
  name VARCHAR,
  birthday DATE,
  occupation VARCHAR,
  salary INT,
  join DATE
}
CREATE TABLE client {
  id INT,
  name VARCHAR,
  birthday DATE,
  address VARCHAR
}

只有您知道这些表的类在层次结构中相连。如果你想让 Hibernate 也知道这一点,你需要在父类中添加@MappedSuperclass注解。没有它,Hibernate 将简单地忽略父类的字段和注释。

带有此注释的类将如下所示:

@MappedSuperclass
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;
}

这是连接类层次结构和数据库的最原始的方式。这种方法实际上只允许您避免类中的重复字段。

HQL 中的数据库查询将只返回类型明确指定的实体。您不能在 HQL 中编写数据库查询并获取所有用户的列表:用户、员工、客户。