คำอธิบาย
ในบทที่แล้ว คุณเห็นว่า 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 "
)