vấn đề bảo tồn

Hôm nay chúng ta sẽ có một lược đồ mới và siêu thú vị - sử dụng các tính năng Hibernate để lưu cấu trúc phân cấp lớp vào cơ sở dữ liệu.

Một hệ thống phân cấp lớp là một tập hợp các lớp liên quan với nhau bằng mối quan hệ kế thừa.

Hãy tưởng tượng rằng bạn có ba lớp mà bạn muốn lưu trữ trong cơ sở dữ liệu:

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

Các lớp được kế thừa lẫn nhau. Và điều thú vị nhất là bạn muốn sử dụng Hibernate để lưu trữ các đối tượng của các lớp này trong cơ sở dữ liệu.

các loại giải pháp

Hibernate có 4 cách khả thi để nó có thể liên kết hệ thống phân cấp lớp với các bảng trong cơ sở dữ liệu:

  • MappedSuperclass
  • bàn đơn
  • Bảng đã tham gia
  • Bàn mỗi lớp

Mỗi chiến lược giả định cấu trúc bảng riêng của nó trong cơ sở dữ liệu. Đôi khi chúng khá phức tạp. Nhưng truy vấn HQL đối với họ rất đơn giản. Đây chính xác là trường hợp những lợi thế của Hibernate được thể hiện rõ ràng.

Tôi chưa bao giờ nghe những thuật ngữ này được dịch sang tiếng Nga, vì vậy tôi cũng khuyên bạn nên phát âm chúng bằng tiếng Anh.

Dưới đây chúng tôi sẽ phân tích ý nghĩa của từng người trong số họ.

@MappedSuperClass

Hãy bắt đầu với giải pháp đơn giản nhất - trong cơ sở dữ liệu, bạn có các bảng riêng biệt 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
}

Chỉ bạn mới biết rằng các lớp cho các bảng này được kết nối trong một hệ thống phân cấp . Nếu bạn cũng muốn Hibernate biết về điều này, bạn cần thêm chú thích @MappedSuperclass vào lớp cha . Không có nó, Hibernate sẽ đơn giản bỏ qua các trường và chú thích của lớp cha.

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

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

Đây là cách nguyên thủy nhất để liên kết hệ thống phân cấp lớp và cơ sở dữ liệu. Cách tiếp cận này thực sự chỉ cho phép bạn tránh các trường trùng lặp trong các lớp.

Các truy vấn cơ sở dữ liệu trong HQL sẽ chỉ trả về thực thể có loại được chỉ định rõ ràng. Bạn không thể viết truy vấn cơ sở dữ liệu trong HQL và nhận danh sách tất cả người dùng: Người dùng, Nhân viên, Khách hàng.