5.1 Mô tả

Và cuối cùng, chiến lược cuối cùng là Bảng mỗi lớp. Nó có nghĩa là một bảng riêng biệt sẽ được sử dụng cho mỗi lớp. Theo một nghĩa nào đó, đây là cùng một MappedSuperClass, chỉ ở dạng cập nhật.

Trước tiên, bạn cần sử dụng một chú thích:

@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)

Các lớp có chú thích này sẽ trông như thế này:


@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
class Client extends User {
	String address;
}

Và bảng riêng cho từng lớp. Ví dụ:


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
}

Sự khác biệt chính là id chuyển qua (Khóa CHÍNH) được sử dụng cho tất cả các bảng. Bạn không thể có các hàng khác nhau có cùng id, không chỉ trong cùng một bảng mà còn trong nhóm bảng này. Hibernate sẽ lo việc này.

5.2 Ví dụ

Thật thú vị khi xem mọi thứ hoạt động như thế nào.

Bạn có thể viết một truy vấn HQL đơn giản để nhận tất cả người dùng: User, Employee, Client :

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

Nhưng đến lượt mình, Hibernate sẽ tạo ra một truy vấn rất thú vị. Nó sẽ thực hiện lựa chọn từ tất cả các bảng, sau đó kết hợp nó thông qua UNION ALL thành một loại bảng ảo và chỉ khi đó nó mới tìm kiếm và/hoặc chọn

Nhưng để hợp nhất các bảng với các cột khác nhau, trước tiên chúng cần được bổ sung bằng các cột giả. Ví dụ: bảng người dùng cần được bổ sung các cột:

  • occupation VARCHAR
  • salary INT
  • join DATE
  • address VARCHAR

Một ví dụ về truy vấn SQL tới bảng người dùng trước khi thực hiện UNION ALL:


SELECT   id,
         name,
         birthday,
         CAST(NULL AS VARCHAR) AS occupation,
         CAST(NULL AS INT) AS salary,
         CAST(NULL AS DATE) AS join,
         CAST(NULL AS VARCHAR) AS address,
         0 AS clazz
FROM  user

Một ví dụ truy vấn SQL tới bảng employee trước khi thực hiện UNION ALL:


SELECT   id,
         name,
         birthday,
         occupation,
         salary,
         join,
         CAST(NULL AS VARCHAR) AS address,
         1 AS clazz
FROM  employee

Một ví dụ về truy vấn SQL tới bảng máy khách trước khi thực hiện UNION ALL:


SELECT  id,
        name,
        birthday,
        CAST(NULL AS VARCHAR) AS occupation,
        CAST(NULL AS INT) AS salary,
        CAST(NULL AS DATE) AS join,
        address,
        2 AS clazz
FROM client

Tin vui là các truy vấn HQL sẽ hoạt động theo cách bạn muốn.

Tin xấu là chúng có thể bị chậm nếu có nhiều dữ liệu trong các bảng. Bởi vì trước tiên, bạn cần chọn dữ liệu từ tất cả các bảng, sau đó kết hợp các hàng của chúng với UNION ALLvà chỉ sau đó lọc.