Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lernen Entitätsbeziehungen und Kaskadentypen | Grundlagen von Hibernate
Java-Datenmanipulation mit Hibernate
course content

Kursinhalt

Java-Datenmanipulation mit Hibernate

Java-Datenmanipulation mit Hibernate

1. JDBC-Übersicht
2. Grundlagen von Hibernate
3. Letzte Feinabstimmungen

book
Entitätsbeziehungen und Kaskadentypen

Entitätsbeziehungen

Wie Sie vielleicht aus dem Kurs über relationale Datenbanken und Normalisierung wissen, gibt es in SQL bestimmte Beziehungen zwischen Tabellen. Ähnlich verhält es sich in Hibernate, wo eine Entität eine andere referenzieren kann und umgekehrt. Diese werden als Entitätsbeziehungen bezeichnet. Es gibt insgesamt 4 Arten solcher Beziehungen.

Eins-zu-Eins

Dieser Beziehungstyp zeigt an, dass eine Entität nur mit einer anderen Entität verbunden ist. Zum Beispiel kann ein Land nur eine Hauptstadt haben. Wenn wir dies in Bezug auf Tabellen und Entitäten darstellen, wird es eine Eins-zu-Eins-Beziehung zwischen ihnen geben. In Hibernate verwenden wir zur Spezifizierung einer solchen Beziehung die @OneToOne Annotation:

Wenn diese Annotation über einem Entitätsfeld vorhanden ist, wird in der entsprechenden Tabelle eine Fremdschlüsselspalte erstellt, die einen Verweis auf den Bezeichner der zugehörigen Entität enthält.

Es wird so aussehen:

Offensichtlich werden in der "cities"-Tabelle Hauptstädte mit ihren IDs gespeichert. Zum Beispiel wird unter der ID 4 "Managua" stehen, unter 11 "Washington" und so weiter.

One-to-Many

In einer solchen Beziehung wird eine Entität mit mehreren anderen Entitäten verbunden sein. Es ist leicht zu verstehen mit dem Beispiel eines Regisseurs und seiner Filme. Ein Regisseur kann viele verschiedene Filme haben, aber jeder Film sollte nur einen Regisseur haben.

Hinweis

Ja, ich weiß, dass es Fälle gibt, in denen mehrere Regisseure an einem Film arbeiten, aber für unser Beispiel ist das jetzt nicht wichtig.

Um eine solche Beziehung zu kennzeichnen, wird die @OneToMany-Annotation über dem Feld in der Entitätsklasse platziert. Das Feld muss eine Liste sein:

Wenn eine solche Annotation über dem Feld vorhanden ist, wird eine separate Tabelle in der Datenbank erstellt, die die Kennungen dieser Entität und der zugehörigen Entität enthält.

Es wird so aussehen:

Solche IDs werden auf beide Entitäten verweisen und die Beziehungen zwischen ihnen anzeigen.

Viele-zu-Eins

Bei diesem Typ sind viele Entitäten mit einer verbunden. Man könnte es als das Gegenteil von Eins-zu-Viele betrachten, und das wäre korrekt. Für ein besseres Verständnis, betrachten Sie das Beispiel der Studenten-Universitäts-Beziehungen. Viele Studenten können mit einer Universität verbunden sein.

Um eine solche Beziehung herzustellen, müssen Sie die @ManyToOne Annotation über dem Feld angeben, das keine Sammlung ist:

Wenn diese Annotation über dem Entitätsfeld vorhanden ist, erhält die entsprechende Tabelle eine Fremdschlüsselspalte, die einen Verweis auf den Bezeichner der zugehörigen Entität enthält.

Es wird so aussehen:

Dies ähnelt One-to-One, aber hier können verschiedene Studenten denselben Verweis auf die Universitäts-ID haben.

Viele-zu-Viele

In dieser Art von Beziehung sind viele Entitäten mit vielen Entitäten verbunden. Sie können sich diese Beziehung in Bezug auf einen Fahrer und ein Auto vorstellen. Ein Fahrer kann viele Autos haben, und ein Auto kann viele Fahrer haben (zum Beispiel in einem Taxiservice).

Im Code müssen Sie die @ManyToMany Annotation über dem Feld in der Entität platzieren:

Wenn diese Annotation über einem Feld der Entität vorhanden ist (das eine Sammlung sein muss), wird in der Datenbank eine separate Tabelle erstellt, die Identifikatoren der aktuellen Entität und der zugehörigen Entität enthält.

Es wird so aussehen:

Wie Sie sehen können, kann ein Fahrer mehrere Autos haben, und ebenso kann ein Auto mehrere Fahrer haben.

Sie haben vielleicht bemerkt, dass wir in einigen Fällen die Annotation nur in einer Klasse angeben müssen, während es in anderen Fällen notwendig ist, sie gleichzeitig in beiden Entitätsklassen anzugeben. Lassen Sie uns dies genauer besprechen.

Unidirektionale und Bidirektionale Beziehungen

Unidirektionale und bidirektionale Beziehungen zwischen Entitäten zeigen an, wie sie interagieren.

  • Unidirektionale Beziehungen: Dies sind die Beziehungen, die wir zuvor besprochen haben. In einer solchen Beziehung wird die Beziehungsannotation nur in einer Entitätsklasse angegeben. Einfach ausgedrückt, die Klasse, die das annotierte Feld enthält, weiß, dass sie mit einer anderen Klasse in Beziehung steht, während die andere Klasse, die die Annotation nicht enthält, sich der Beziehung nicht bewusst ist. Es ist nicht kompliziert, aber wir sind mehr an dem zweiten Fall interessiert;

  • Bidirektionale Beziehungen: In dieser Art von Beziehung ist Klasse A sich ihrer Beziehung zu Klasse B bewusst, ebenso wie Klasse B sich ihrer Beziehung zu Klasse A bewusst ist. Die Beziehungsannotation wird in beiden Entitätsklassen angegeben und sieht folgendermaßen aus:

java

A

java

B

copy
1234567891011
@Entity public class A { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; private String name; @OneToMany private List<B> list; }

Interaktion zwischen diesen beiden Entitäten erfolgt in beide Richtungen.

Um Konsistenz während der Datenoperationen sicherzustellen, müssen wir die "besitzende Seite" und die "inverse Seite" definieren. Die besitzende Seite ist die Seite, die die Beziehung kontrolliert, und Aktualisierungen der Beziehung in der Datenbank erfolgen nur nach Änderungen auf der besitzenden Seite.

Um die besitzende Seite zu bestimmen, verwenden wir einen Parameter in der Beziehungsannotation. Der mappedBy-Parameter verwendet den Namen des Feldes in der Entität, die wir zur besitzenden Seite machen wollen. Mit anderen Worten, wir verwenden diese Annotation in der Entität, die wir zur inversen Seite machen wollen.

Für ein klareres Beispiel, lassen Sie uns die Klasse B zur besitzenden Seite machen:

Jetzt ist die Entität B die besitzende Seite in diesen bidirektionalen Beziehungen geworden. Die Daten werden nur dann in die Datenbank geschrieben, wenn Änderungen in der Klasse B vorgenommen werden.

Dies wird verwendet, um die Erstellung einer neuen Tabelle zu vermeiden, die die Bezeichner dieser beiden Entitäten enthält. Stattdessen wird nun eine separate Spalte, "A_id", zur Tabelle der Entität B hinzugefügt, in der die Beziehungs-IDs angegeben werden.

Es gilt als gute Praxis, die "ManyToOne"-Seite zur besitzenden Seite zu machen. Bei bidirektionalen Beziehungen "Many-to-Many" kann jede Seite als besitzende Seite festgelegt werden.

Später werden wir dies in der Praxis anwenden, und Sie werden besser verstehen, wie es funktioniert und warum es notwendig ist.

Abrufarten

In Entitätsbeziehungen werden verschiedene Abrufarten verwendet. Es gibt zwei davon, lassen Sie uns jede besprechen:

  • EAGER bedeutet, dass alle notwendigen Daten in einer einzigen Abfrage abgerufen werden. Wenn wir eine Entität aus der Datenbank abrufen, die @OneToOne oder @ManyToOne Felder hat, erhalten wir auch vollständige Informationen über diese verwandten Entitäten. Das bedeutet, dass wir mit einer Abfrage an die Datenbank sofort Informationen aus zwei Tabellen abrufen, was Ressourcen, Speicher und Ausführungszeit verbraucht. Eine solche Abrufart hat erhebliche Auswirkungen auf die Optimierung;

  • LAZY bedeutet, dass Daten aus der Datenbank nur dann abgerufen werden, wenn sie tatsächlich für eine bestimmte Operation benötigt werden. Wenn wir eine Entität aus der Datenbank abrufen, die @OneToMany oder @ManyToMany Felder hat, erhalten wir keine Informationen über diese verwandten Entitäten. Dies ist ein wesentlicher Vorteil, da wir keine unnötigen Informationen aus der Datenbank abrufen, nur die Daten, die wir benötigen. Das bedeutet, dass nur die Tabelle, auf die wir uns beziehen, betroffen ist, ohne die Tabellen zu berühren, die mit dieser Entität verbunden sind.

Hinweis

Es ist ziemlich einfach, sich das zu merken: Beziehungen, die auf Many enden, haben eine Abrufart von LAZY; der Rest wird EAGER sein.

Es wird empfohlen, immer die LAZY-Abrufart zu verwenden, da sie den Code optimierter macht. Sie können dies mit dem Befehl fetch = FetchType.LAZY in den Annotationsparametern tun.

So sieht es im Code aus:

Nun, wenn wir eine Abfrage für diese Entität ausführen, werden wir nur sie beeinflussen und nur auf andere Daten zugreifen, wenn es notwendig ist.

Kaskadentypen

Jetzt, da wir gelernt haben, wie wir nur mit der Entität interagieren, mit der wir arbeiten, lernen wir, wie wir spezifische Felder angeben, auf die die Interaktion bei der Beziehung von Entitäten in jedem Fall propagiert werden soll. Kaskaden werden uns dabei helfen.

Hinweis

Solche Kaskaden sind Teil der JPA ( Jakarta Persistence API ) Bibliothek, die die Elternklasse von Hibernate ist. Daher können wir in Hibernate auch solche Klassen verwenden.

Es gibt insgesamt 4 Typen:

  • PERSIST — das Aufrufen der persist()-Methode wird auf verwandte Entitäten übertragen;
  • MERGE — das Aufrufen der merge()-Methode wird auf verwandte Entitäten übertragen;
  • REMOVE — das Aufrufen der remove()-Methode wird auf verwandte Entitäten übertragen;
  • ALL - alle oben genannten Operationen werden auf verwandte Entitäten übertragen.

Jeder dieser Kaskadentypen erfüllt seinen Zweck.

Stellen wir uns eine Situation vor, in der wir einen neuen Studenten speichern und Änderungen auch an der "Universitäten"-Tabelle vorgenommen werden sollen, zum Beispiel Erhöhung der Anzahl der Studenten.

So können wir dies umsetzen:

In diesem Fall werden bei Änderungen mit der persist()-Methode an der Student-Entität auch Änderungen an der University-Entität vorgenommen.

Zuweisung einer Abteilung zu einem Mitarbeiter

Für den Moment ist die beängstigende Theorie in diesem Kapitel abgeschlossen.

Erinnern wir uns nun an das Mitarbeiterverwaltungsprojekt, an dem wir gearbeitet haben, und denken wir über die Beziehung zwischen den Employee- und Department-Entitäten nach. Es ist offensichtlich, dass ein Mitarbeiter nur in einer Abteilung arbeiten kann, während viele Mitarbeiter in einer Abteilung arbeiten können. In diesem Fall können wir schließen, dass eine One-to-Many-Beziehung von der Seite des Employee und eine Many-to-One-Beziehung von der Seite des Department hergestellt wird.

Lassen Sie uns eine unidirektionale Beziehung in diesen Tabellen herstellen.

Um dies zu erreichen, fügen wir die Annotation @ManyToOne(fetch = FetchType.LAZY) hinzu und verwenden auch die neue Annotation JoinColumn(name = "department_id"), um die Erstellung einer neuen Tabelle zu vermeiden.

Ja, dieser Ansatz hat auch seinen Platz, da bidirektionale Beziehungen ziemlich komplex zu verstehen und zu implementieren sind, und auf diese Weise erhalten wir die Vorteile von bidirektionalen Beziehungen ohne unnötigen Aufwand.

Die Employee-Entität wird so aussehen:

Es sind keine weiteren Änderungen erforderlich, da Hibernate alles für uns erledigt. Nun verwenden wir die getAll()-Methode, die im vorherigen Kapitel implementiert wurde, um die Änderungen zu sehen:

1. Welche Art von Beziehung wird am besten durch einen Regisseur und seine Filme dargestellt?

2. In einer Viele-zu-Eins-Beziehung, wo wird die Fremdschlüsselspalte erstellt?

3. Was bedeutet die @ManyToMany Annotation in Hibernate?

4. Welcher Fetch-Typ wird empfohlen, um Code in Hibernate zu optimieren?

5. Welche Annotation wird verwendet, um bei der Definition einer Many-to-One-Beziehung in Hibernate den Spaltennamen in der Datenbank anzugeben?

Welche Art von Beziehung wird am besten durch einen Regisseur und seine Filme dargestellt?

Welche Art von Beziehung wird am besten durch einen Regisseur und seine Filme dargestellt?

Wählen Sie die richtige Antwort aus

In einer Viele-zu-Eins-Beziehung, wo wird die Fremdschlüsselspalte erstellt?

In einer Viele-zu-Eins-Beziehung, wo wird die Fremdschlüsselspalte erstellt?

Wählen Sie die richtige Antwort aus

Was bedeutet die `@ManyToMany` Annotation in Hibernate?

Was bedeutet die @ManyToMany Annotation in Hibernate?

Wählen Sie die richtige Antwort aus

Welcher Fetch-Typ wird empfohlen, um Code in Hibernate zu optimieren?

Welcher Fetch-Typ wird empfohlen, um Code in Hibernate zu optimieren?

Wählen Sie die richtige Antwort aus

Welche Annotation wird verwendet, um bei der Definition einer Many-to-One-Beziehung in Hibernate den Spaltennamen in der Datenbank anzugeben?

Welche Annotation wird verwendet, um bei der Definition einer Many-to-One-Beziehung in Hibernate den Spaltennamen in der Datenbank anzugeben?

Wählen Sie die richtige Antwort aus

War alles klar?

Wie können wir es verbessern?

Danke für Ihr Feedback!

Abschnitt 2. Kapitel 9
We're sorry to hear that something went wrong. What happened?
some-alt