Penerangan
Dalam pelajaran sebelumnya, anda melihat bahawa Hibernate menggunakan lajur DTYPE VARCHAR khas untuk menyimpan nama kelas Entiti. Lajur sedemikian dipanggil diskriminator . Ia digunakan untuk menentukan dengan jelas kelas mana yang hendak dibuat untuk baris tertentu dalam pangkalan data.
Anda boleh memanipulasi lajur ini dengan anotasi @DiscriminatorColumn . Contoh:
@DiscriminatorColumn(name="column_name", discriminatorType = DiscriminatorType.INTEGER)
Menurut spesifikasi JPA, diskriminator boleh mempunyai jenis berikut:
- TALI
- CHAR
- INTEGER
Walau bagaimanapun, Hibernate membenarkan anda mengembangkan sedikit senarai ini. Ia menyokong jenis Java ini: String, char, int, byte, short, boolean.
Jika kita menggunakan jenis INTEGER, maka bagaimana untuk mengekod nama kelas Entiti di dalamnya? Untuk ini, anotasi lain digunakan - @DiscriminatorValue .
Lihat contoh:
@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;
}
Dalam contoh di atas, kami memberitahu Hibernate bahawa diskriminator akan menggunakan lajur user_type, yang akan menyimpan nombor. Jika ia menyimpan nilai 1, maka ia bermakna jenis baris ialah Pekerja, jika 2 disimpan, maka jenis baris ialah Klien. Simple dan cantik.
@DiscriminatorValue
Tetapi bukan itu sahaja. Anda boleh memberitahu Hibernate cara mentafsir jenis rentetan apabila diskriminatornya adalah NULL.
Ia sebenarnya sangat mudah. Anda menentukan nilai nol untuk anotasi @DiscriminatorValue . Sebagai contoh, seperti ini:
@DiscriminatorValue("null")
Contoh kelas:
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="user_type", discriminatorType = DiscriminatorType.INTEGER)
@DiscriminatorValue("null")
@Entity
class User {
int id;
String name;
LocalDate birthday;
}
Kami telah memberitahu Hibernate bahawa mana-mana baris jadual yang mempunyai NULL dalam lajur user_type harus ditafsirkan sebagai objek jenis Pengguna.
Tetapi bukan itu sahaja. Terdapat satu lagi nilai menarik untuk anotasi @DiscriminatorValue.
Inilah ini:
@DiscriminatorValue("not null")
Contoh kelas:
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="user_type", discriminatorType = DiscriminatorType.INTEGER)
@DiscriminatorValue("not null")
@Entity
class User {
int id;
String name;
LocalDate birthday;
}
Dengan anotasi ini, kami memberitahu Hibernate bahawa mana-mana baris jadual dengan nilai bukan NULL dalam lajur user_type harus ditafsirkan sebagai objek jenis Pengguna. Tetapi ini hanya untuk kes jika kelas tidak dijumpai yang mempunyai nombor yang diperlukan dinyatakan dengan jelas.
Beginilah cara ia berfungsi untuk nilai yang berbeza dari diskriminasi:
- 0 - cipta objek jenis Pengguna
- 1 - cipta objek jenis Pekerja
- 2 - cipta objek jenis Klien
- 3 - cipta objek jenis Pengguna
- 4 - cipta objek jenis Pengguna
@Formula Diskriminator
Tetapi bukan itu sahaja. Untuk diskriminator kami, kami boleh menentukan formula integer yang mana ia akan mengira nilai untuk anotasi @DiscriminatorValue .
Terdapat anotasi khas untuk ini, ia dipanggil @DiscriminatorFormula .
Contoh:
@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;
}
Nilai yang dikembalikan oleh @DiscriminatorFormula akan dibandingkan oleh Hibernate dengan nilai yang dinyatakan dalam anotasi @DiscriminatorValue . Dengan itu, anda boleh menulis senario yang agak rumit:
@DiscriminatorFormula(
"case when address is not null " +
"then 'Client' " +
"else (" +
" case when occupation is not null " +
" then 'Employee' " +
" else 'Unknown' " +
" end) " +
"end "
)