คำอธิบาย

ในบทที่แล้ว คุณเห็นว่า Hibernate ใช้คอลัมน์ DTYPE VARCHAR พิเศษเพื่อจัดเก็บชื่อของคลาสเอนทิตี คอลัมน์ดังกล่าวเรียกว่าdiscriminator ใช้เพื่อกำหนดคลาสที่จะสร้างสำหรับแถวที่กำหนดในฐานข้อมูลอย่างชัดเจน

คุณสามารถจัดการคอลัมน์นี้ด้วยคำ อธิบายประกอบ @DiscriminatorColumn ตัวอย่าง:

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

ตามข้อกำหนดของ JPA ผู้เลือกปฏิบัติสามารถมีประเภทต่อไปนี้:

  • STRING
  • ชาร์
  • จำนวนเต็ม

อย่างไรก็ตาม Hibernate ช่วยให้คุณสามารถขยายรายการนี้ได้เล็กน้อย รองรับประเภท Java เหล่านี้: String, char, int, byte, short, boolean

หากเราใช้ประเภท INTEGER จะเข้ารหัสชื่อของคลาส Entity ในนั้นได้อย่างไร สำหรับสิ่งนี้ จะใช้คำอธิบายประกอบอื่น- @DiscriminatorValue

ดูตัวอย่าง:

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

ในตัวอย่างด้านบน เราบอก Hibernate ว่า discriminator จะใช้คอลัมน์ user_type ซึ่งจะเก็บตัวเลข หากเก็บค่า 1 แสดงว่าประเภทแถวคือพนักงาน หากเก็บเป็น 2 แสดงว่าประเภทแถวคือลูกค้า เรียบง่ายและสวยงาม

@DiscriminatorValue

แต่นั่นไม่ใช่ทั้งหมด คุณสามารถบอก Hibernate ได้ว่าจะตีความประเภทของสตริงอย่างไรเมื่อตัวจำแนกเป็น NULL

จริงๆแล้วมันง่ายมาก คุณระบุค่า Null สำหรับคำ อธิบายประกอบ @DiscriminatorValue ตัวอย่างเช่น:

@DiscriminatorValue("null")

ตัวอย่างคลาส:

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

เราได้บอก Hibernate ว่าแถวของตารางที่มีค่า NULL ในคอลัมน์ user_type ควรถูกตีความเป็นวัตถุประเภท User

แต่นั่นไม่ใช่ทั้งหมด มีค่าที่น่าสนใจอีกอย่างหนึ่งสำหรับคำอธิบายประกอบ @DiscriminatorValue

นี่คือ:

@DiscriminatorValue("not null")

ตัวอย่างคลาส:

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

ด้วยคำอธิบายประกอบนี้ เราได้บอก Hibernate ว่าแถวของตารางใดๆ ที่มีค่าไม่เป็น NULL ในคอลัมน์ user_type ควรถูกตีความเป็นอ็อบเจกต์ประเภท User แต่นี่เป็นเพียงกรณีที่ไม่พบคลาสที่มีการระบุจำนวนที่ต้องการอย่างชัดเจน

นี่คือวิธีการทำงานสำหรับค่าต่างๆ ของผู้เลือกปฏิบัติ:

  • 0 - สร้างวัตถุประเภท User
  • 1 - สร้างวัตถุประเภทพนักงาน
  • 2 - สร้างวัตถุประเภทClient
  • 3 - สร้างวัตถุประเภท User
  • 4 - สร้างวัตถุประเภท User

@DiscriminatorFormula

แต่นั่นไม่ใช่ทั้งหมด สำหรับ discriminator เราสามารถระบุสูตรจำนวนเต็มซึ่งจะคำนวณค่าสำหรับ คำ อธิบาย ประกอบ @DiscriminatorValue

มีคำอธิบายประกอบพิเศษสำหรับสิ่งนี้ เรียกว่า@DiscriminatorFormula

ตัวอย่าง:

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

ค่าที่ส่งคืนโดย@DiscriminatorFormulaจะถูกเปรียบเทียบโดย Hibernate กับค่าที่ระบุใน คำ อธิบาย ประกอบ @DiscriminatorValue ด้วยวิธีนี้ คุณสามารถเขียนสถานการณ์ที่ค่อนข้างซับซ้อนได้:

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