Paglalarawan
Sa nakaraang aralin, nakita mo na ang Hibernate ay gumagamit ng isang espesyal na DTYPE VARCHAR column upang iimbak ang pangalan ng isang klase ng Entity. Ang nasabing column ay tinatawag na discriminator . Ito ay ginagamit upang hindi malabo na matukoy kung aling klase ang lilikha para sa isang naibigay na hilera sa database.
Maaari mong manipulahin ang column na ito gamit ang @DiscriminatorColumn annotation . Halimbawa:
@DiscriminatorColumn(name="column_name", discriminatorType = DiscriminatorType.INTEGER)
Ayon sa detalye ng JPA, ang isang discriminator ay maaaring magkaroon ng mga sumusunod na uri:
- STRING
- CHAR
- INTEGER
Gayunpaman, pinapayagan ka ng Hibernate na palawakin nang kaunti ang listahang ito. Sinusuportahan nito ang mga uri ng Java na ito: String, char, int, byte, short, boolean.
Kung gagamitin natin ang uri ng INTEGER, kung gayon paano i-encode ang pangalan ng klase ng Entity dito? Para dito, ginagamit ang isa pang anotasyon - @DiscriminatorValue .
Tingnan ang isang halimbawa:
@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;
}
Sa halimbawa sa itaas, sinabi namin sa Hibernate na gagamitin ng discriminator ang column ng user_type, na mag-iimbak ng mga numero. Kung iniimbak nito ang halaga 1, nangangahulugan ito na ang uri ng hilera ay Empleyado, kung ang 2 ay nakaimbak, kung gayon ang uri ng hilera ay Kliyente. Simple at maganda.
@DiscriminatorValue
Ngunit hindi lang iyon. Maaari mong sabihin sa Hibernate kung paano i-interpret ang uri ng isang string kapag ang discriminator nito ay NULL.
Ito ay talagang napaka-simple. Tinukoy mo ang null value para sa @DiscriminatorValue annotation . Halimbawa, tulad nito:
@DiscriminatorValue("null")
Halimbawa ng klase:
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="user_type", discriminatorType = DiscriminatorType.INTEGER)
@DiscriminatorValue("null")
@Entity
class User {
int id;
String name;
LocalDate birthday;
}
Sinabi namin sa Hibernate na ang anumang hilera ng talahanayan na may NULL sa column ng user_type ay dapat bigyang-kahulugan bilang isang object ng uri ng User.
Ngunit hindi lang iyon. May isa pang kawili-wiling halaga para sa @DiscriminatorValue annotation.
Narito ito:
@DiscriminatorValue("not null")
Halimbawa ng klase:
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="user_type", discriminatorType = DiscriminatorType.INTEGER)
@DiscriminatorValue("not null")
@Entity
class User {
int id;
String name;
LocalDate birthday;
}
Sa annotation na ito, sinabi namin sa Hibernate na ang anumang hilera ng talahanayan na may non-NULL na halaga sa column ng user_type ay dapat bigyang-kahulugan bilang isang object ng uri ng User. Ngunit ito ay para lamang sa kaso kung ang isang klase ay hindi nahanap na may kinakailangang numero na tahasang tinukoy.
Ito ay kung paano ito gagana para sa iba't ibang mga halaga ng mga discriminator:
- 0 - lumikha ng isang object ng uri ng User
- 1 - lumikha ng isang bagay ng uri ng Empleyado
- 2 - lumikha ng isang bagay ng uri ng Kliyente
- 3 - lumikha ng isang object ng uri ng User
- 4 - lumikha ng isang bagay ng uri ng User
@DiscriminatorFormula
Ngunit hindi lang iyon. Para sa aming discriminator, maaari kaming tumukoy ng integer formula kung saan kakalkulahin nito ang mga value para sa @DiscriminatorValue annotation .
Mayroong espesyal na anotasyon para dito, ito ay tinatawag na @DiscriminatorFormula .
Halimbawa:
@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;
}
Ang mga value na ibinalik ng @DiscriminatorFormula ay ihahambing ng Hibernate sa mga value na tinukoy sa @DiscriminatorValue annotation . Gamit ito, maaari kang magsulat ng medyo kumplikadong mga sitwasyon:
@DiscriminatorFormula(
"case when address is not null " +
"then 'Client' " +
"else (" +
" case when occupation is not null " +
" then 'Employee' " +
" else 'Unknown' " +
" end) " +
"end "
)