Sự miêu tả

Trong bài học trước, bạn đã thấy rằng Hibernate sử dụng một cột DTYPE VARCHAR đặc biệt để lưu trữ tên của một lớp Thực thể. Cột như vậy được gọi là cột phân biệt đối xử . Nó được sử dụng để xác định rõ ràng lớp nào sẽ tạo cho một hàng nhất định trong cơ sở dữ liệu.

Bạn có thể thao tác với cột này bằng chú thích @DiscriminatorColumn . Ví dụ:

@DiscriminatorColumn(name="column_name",   discriminatorType = DiscriminatorType.INTEGER)

Theo đặc tả JPA, một bộ phân biệt đối xử có thể có các loại sau:

  • SỢI DÂY
  • CHAR
  • số nguyên

Tuy nhiên, Hibernate cho phép bạn mở rộng danh sách này một chút. Nó hỗ trợ các kiểu Java sau: String, char, int, byte, short, boolean.

Nếu chúng ta sử dụng kiểu INTEGER thì làm sao để mã hóa tên của lớp Thực thể trong đó? Đối với điều này, một chú thích khác được sử dụng - @DiscriminatorValue .

Nhìn vào một ví dụ:

@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="user_type",   discriminatorType = DiscriminatorType.INTEGER)
@Entity
class User {
  int id;
  String name;
  LocalDate birthday;
}
@Entity
@DiscriminatorValue("1")
class Employee extends User {
 	String occupation;
 	int salary;
 	LocalDate join;
}
@Entity
@DiscriminatorValue("2")
class Client extends User {
   String address;
}

Trong ví dụ trên, chúng tôi đã nói với Hibernate rằng bộ phân biệt đối xử sẽ sử dụng cột user_type, cột này sẽ lưu trữ các số. Nếu nó lưu giá trị 1 thì có nghĩa là loại hàng là Nhân viên, nếu nó lưu giá trị 2 thì loại hàng là Khách hàng. Đơn giản và đẹp.

@DiscriminatorValue

Nhưng đó không phải là tất cả. Bạn có thể cho Hibernate biết cách diễn giải loại chuỗi khi phân biệt đối xử của nó là NULL.

Nó thực sự rất đơn giản. Bạn chỉ định giá trị null cho chú thích @DiscriminatorValue . Ví dụ, như thế này:

@DiscriminatorValue("null")

Ví dụ về lớp:

@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="user_type",   discriminatorType = DiscriminatorType.INTEGER)
@DiscriminatorValue("null")
@Entity
class User {
  int id;
  String name;
  LocalDate birthday;
}

Chúng tôi đã nói với Hibernate rằng bất kỳ hàng nào trong bảng có NULL trong cột user_type sẽ được hiểu là một đối tượng thuộc loại Người dùng.

Nhưng đó không phải là tất cả. Có một giá trị thú vị khác cho chú thích @DiscriminatorValue.

Đây là cái này:

@DiscriminatorValue("not null")

Ví dụ về lớp:

@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="user_type",   discriminatorType = DiscriminatorType.INTEGER)
@DiscriminatorValue("not null")
@Entity
class User {
  int id;
  String name;
  LocalDate birthday;
}

Với chú thích này, chúng tôi đã nói với Hibernate rằng bất kỳ hàng nào trong bảng có giá trị không NULL trong cột user_type sẽ được hiểu là một đối tượng thuộc loại Người dùng. Nhưng điều này chỉ dành cho trường hợp nếu không tìm thấy một lớp có số lượng bắt buộc được chỉ định rõ ràng.

Đây là cách nó sẽ hoạt động đối với các giá trị khác nhau của các bộ phân biệt đối xử:

  • 0 - tạo một đối tượng kiểu Người dùng
  • 1 - tạo một đối tượng kiểu Nhân viên
  • 2 - tạo một đối tượng kiểu Client
  • 3 - tạo một đối tượng kiểu Người dùng
  • 4 - tạo một đối tượng kiểu Người dùng

@DiscriminatorFormula

Nhưng đó không phải là tất cả. Đối với bộ phân biệt đối xử của chúng tôi, chúng tôi có thể chỉ định một công thức số nguyên mà theo đó nó sẽ tính toán các giá trị cho chú thích @DiscriminatorValue .

Có một chú thích đặc biệt cho điều này, nó được gọi là @DiscriminatorFormula .

Ví dụ:

@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="user_type",   discriminatorType = DiscriminatorType.INTEGER)
@DiscriminatorFormula("case when ‘join’ is not null then 1 else 2 end")
@Entity
class User {
  int id;
  String name;
  LocalDate birthday;
}
@Entity
@DiscriminatorValue("1")
class Employee extends User {
 	String occupation;
 	int salary;
 	LocalDate join;
}
@Entity
@DiscriminatorValue("2")
class Client extends User {
   String address;
}

Các giá trị được trả về bởi @DiscriminatorFormula sẽ được Hibernate so sánh với các giá trị được chỉ định trong các chú thích @DiscriminatorValue . Với nó, bạn có thể viết các kịch bản khá phức tạp:

@DiscriminatorFormula(
           	"case when address is not null " +
           	"then 'Client' " +
           	"else (" +
           	"   case when occupation is not null " +
           	"   then 'Employee' " +
           	"   else 'Unknown' " +
           	"   end) " +
           	"end "
)