Beschreibung

In der vorherigen Lektion haben Sie gesehen, dass Hibernate eine spezielle DTYPE VARCHAR-Spalte verwendet, um den Namen einer Entity-Klasse zu speichern. Eine solche Spalte wird als Diskriminator bezeichnet . Es wird verwendet, um eindeutig zu bestimmen, welche Klasse für eine bestimmte Zeile in der Datenbank erstellt werden soll.

Sie können diese Spalte mit der Annotation @DiscriminatorColumn bearbeiten . Beispiel:

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

Gemäß der JPA-Spezifikation kann ein Diskriminator die folgenden Typen haben:

  • STRING
  • VERKOHLEN
  • GANZE ZAHL

Mit Hibernate können Sie diese Liste jedoch etwas erweitern. Es unterstützt diese Java-Typen: String, char, int, byte, short, boolean.

Wenn wir den Typ INTEGER verwenden, wie kodiert man dann den Namen der Entity-Klasse darin? Hierzu wird eine weitere Annotation verwendet – @DiscriminatorValue .

Schauen Sie sich ein Beispiel an:

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

Im obigen Beispiel haben wir Hibernate mitgeteilt, dass der Diskriminator die Spalte user_type verwenden wird, in der Zahlen gespeichert werden. Wenn der Wert 1 gespeichert ist, bedeutet dies, dass der Zeilentyp „Mitarbeiter“ ist. Wenn 2 gespeichert ist, ist der Zeilentyp „Kunde“. Einfach und schön.

@DiskriminatorValue

Aber das ist nicht alles. Sie können Hibernate mitteilen, wie der Typ einer Zeichenfolge interpretiert werden soll, wenn ihr Diskriminator NULL ist.

Es ist eigentlich ganz einfach. Sie geben den Nullwert für die Annotation @DiscriminatorValue an . Zum Beispiel so:

@DiscriminatorValue("null")

Klassenbeispiel:

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

Wir haben Hibernate mitgeteilt, dass jede Tabellenzeile, die NULL in der Spalte „user_type“ enthält, als Objekt vom Typ „Benutzer“ interpretiert werden sollte.

Aber das ist nicht alles. Es gibt einen weiteren interessanten Wert für die Annotation @DiscriminatorValue.

Hier ist das:

@DiscriminatorValue("not null")

Klassenbeispiel:

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

Mit dieser Annotation haben wir Hibernate mitgeteilt, dass jede Tabellenzeile mit einem Nicht-NULL-Wert in der Spalte „user_type“ als Objekt vom Typ „Benutzer“ interpretiert werden soll. Dies ist jedoch nur dann der Fall, wenn keine Klasse gefunden wird, für die die erforderliche Anzahl explizit angegeben ist.

So funktioniert es für verschiedene Werte der Diskriminatoren:

  • 0 – Erstellen Sie ein Objekt vom Typ Benutzer
  • 1 - Erstellen Sie ein Objekt vom Typ Mitarbeiter
  • 2 - Erstellen Sie ein Objekt vom Typ Client
  • 3 - Erstellen Sie ein Objekt vom Typ Benutzer
  • 4 - Erstellen Sie ein Objekt vom Typ Benutzer

@DiscriminatorFormula

Aber das ist nicht alles. Für unseren Diskriminator können wir eine Ganzzahlformel angeben, nach der die Werte für die Annotation @DiscriminatorValue berechnet werden .

Hierfür gibt es eine spezielle Anmerkung, sie heißt @DiscriminatorFormula .

Beispiel:

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

Die von @DiscriminatorFormula zurückgegebenen Werte werden von Hibernate mit den in den @DiscriminatorValue- Annotationen angegebenen Werten verglichen . Damit können Sie recht komplexe Szenarien schreiben:

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