Sự miêu tả

Cách tiếp cận tiếp theo để lưu trữ một hệ thống phân cấp lớp là lưu trữ tất cả các lớp trong hệ thống phân cấp trong một bảng duy nhất . Chiến lược này được gọi là Bảng đơn .

Ví dụ, như thế này:

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

Đó là, chúng tôi có một bảng, trong đó các cột cho tất cả các lớp trong cấu trúc phân cấp của chúng tôi được đánh dấu bằng các màu khác nhau. Ngoài ra còn có một cột dịch vụ đặc biệt DTYPE VARCHAR , nơi Hibernate sẽ lưu trữ tên của lớp Thực thể.

Điều duy nhất còn lại phải làm là giải thích cho Hibernate rằng dữ liệu của các lớp Thực thể hiện được lưu trữ trong cơ sở dữ liệu trong một bảng. Điều này có thể được thực hiện bằng cách sử dụng chú thích @Inheritance :

@Inheritance(strategy = InheritanceType.SINGLE_TABLE)

Một ví dụ về các lớp học của chúng tôi:

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

Dữ liệu được lưu trữ như thế nào

Bây giờ, hãy viết một ví dụ trong đó chúng ta tạo một vài thực thể và lưu chúng vào cơ sở dữ liệu:

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);

Khi lưu vào cơ sở dữ liệu, câu truy vấn SQL sau sẽ được thực hiện:

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')

Khi lưu dữ liệu vào một bảng, Hibernate chỉ chuyển các trường thực thể được biết đến với nó. Điều này có nghĩa là các cột không xác định sẽ là NULL.

Và điều này có nghĩa là bạn không thể chỉ định loại NOT NULL cho cột nghề nghiệp, vì khi một khách hàng được lưu trữ trong cùng một bảng, nghề nghiệp của anh ta sẽ là NULL. Đây là một trong những nhược điểm của việc lưu trữ các thực thể khác nhau trong cùng một bảng.

Trường cuối cùng trong truy vấn SQL là cột DTYPE, chứa tên của lớp Thực thể. Nó được Hibernate sử dụng khi bạn muốn đọc dữ liệu từ bảng của mình.

Ví dụ:

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

Truy vấn này sẽ trả về một danh sách tất cả các đối tượng kiểu người dùng được lưu trữ trong cơ sở dữ liệu: Người dùng, Nhân viên và Khách hàng. Dựa trên cột DTYPE, loại thực thể sẽ được xác định chính xác và một đối tượng của lớp chính xác sẽ được tạo.

Trong trường hợp của chúng tôi, sẽ có hai đối tượng trong danh sách tài khoản: loại Nhân viên và loại Khách hàng.

quy tắc HQL.