@ManyToOne

SQL & Hibernate
Level 13 , Lektion 1
Verfügbar

2.1 Verlinkung auf Tabellenebene

Wir haben gesehen, wie Hibernate Sammlungen in Hilfstabellen speichert. Lassen Sie uns nun herausfinden, wie Sie Beziehungen zwischen vollwertigen Tabellen organisieren, in denen echte Entity-Klassen gespeichert sind.

Es gibt vier Arten von Beziehungen zwischen Entity-Klassen in Hibernate:

  • eins zu eins
  • eins -zu- viele
  • viele zu eins
  • viele zu viele

Und wir beginnen die Analyse mit der einfachsten Option – viele -zu- eins .

Sie sind bereits auf eine solche Beziehung zwischen Tabellen in SQL gestoßen. So sieht es normalerweise aus:

Ausweis Name Beruf Gehalt Alter Beitrittsdatum
1 Iwanow Iwan Programmierer 100000 25 30.06.2012
2 Petrov Petr Programmierer 80000 23 12.08.2013
3 Iwanow Sergej Prüfer 40000 dreißig 01.01.2014
4 Rabinovich Moisha Direktor 200000 35 12.05.2015
5 Kirienko Anastasia Büroleiter 40000 25 10.10.2015
6 Vaska Der Kater 1000 3 11.11.2018

Mitarbeitertabelle:

Diese Tabelle hat die folgenden Spalten:

  • id INT
  • Namen VARCHAR
  • Beruf VARCHAR
  • Gehalt INT
  • Alter INT
  • join_date DATUM

Und so sieht die Aufgabentabelle aus, die Aufgaben für Mitarbeiter enthält:

Ausweis Angestellten ID Name Termin
1 1 Beheben Sie einen Fehler im Frontend 01.06.2022
2 2 Beheben Sie einen Fehler im Backend 15.06.2022
3 5 Kaffee kaufen 01.07.2022
4 5 Kaffee kaufen 01.08.2022
5 5 Kaffee kaufen 01.09.2022
6 (NULL) Räumen Sie das Büro auf (NULL)
7 4 Das Leben genießen (NULL)
8 6 Das Leben genießen (NULL)

Diese Tabelle hat nur 4 Spalten:

  • id – eindeutige Aufgabennummer (und Zeilen in der Tabelle);
  • Employee_id – Mitarbeiter-ID aus der Mitarbeitertabelle, der die Aufgabe zugewiesen ist;
  • Name – Name und Beschreibung der Aufgabe;
  • Frist – die Zeit, bis zu der die Aufgabe abgeschlossen sein muss.

Wir sehen, dass viele Zeilen in der Aufgabentabelle auf einen einzelnen Eintrag in der Mitarbeitertabelle verweisen können. Eine solche Beziehung auf Tabellenebene wird als Viele-zu- Eins-Beziehung bezeichnet.

2.2 Beziehung zur Java-Klassenebene

Neben der Kommunikation auf Tabellenebene können Sie in Hibernate auch die Kommunikation auf der Ebene von Entity-Klassen organisieren. Dies geschieht mit einer Annotation @ManyToOne.

Aber zuerst erstellen wir einfach zwei Klassen: Employee und EmployeeTask :


@Entity
@Table(name="employee")
class Employee {
   @Column(name="id")
   public Integer id;
 
   @Column(name="name")
   public String name;
 
   @Column(name="occupation")
   public String occupation;
 
   @Column(name="salary")
   public Integer salary;
 
   @Column(name="join_date")
   public Date join;
}

Und eine zweite Klasse zum Speichern von Mitarbeiterjobs:


@Entity
@Table(name="task")
class EmployeeTask {
   @Column(name="id")
   public Integer id;
 
   @Column(name="name")
   public String description;
 
  @Column(name="employee_id")
   public Integer employeeId;
 
   @Column(name="deadline")
   public Date deadline;
}

Mit diesen Klassen ist alles in Ordnung, aber es gibt keine Beziehung zwischen ihnen, die die Tatsache widerspiegeln würde, dass das Feld „employeeId“ der Klasse „EmployeeTask“ auf das Feld „id“ der Klasse „Employee“ verweist. Es ist Zeit, das Problem zu beheben

2.3 @ManyToOne-Annotation.

Erstens sind wir es in Java gewohnt, mit Objekten (und Objektreferenzen) und nicht mit deren ID zu operieren. Lassen Sie uns also zunächst anstelle des Felds „employeeId“ in der Klasse „EmployeeTask“ einfach auf ein Objekt vom Typ „Employee“ verweisen. So wird unsere neue Klasse aussehen:


@Entity
@Table(name="task")
class EmployeeTask {
   @Column(name="id")
   public Integer id;
 
   @Column(name="name")
   public String description;
 
   @ManyToOne
   @JoinColumn(name = "employee_id")
   public Employee employee;
 
   @Column(name="deadline")
   public Date deadline;
}

Mithilfe der Annotation @ManyToOne haben wir darauf hingewiesen, dass viele EmployeeTask-Objekte auf ein Objekt vom Typ Employee verweisen können. Mithilfe der Annotation haben wir außerdem @JoinColumnangegeben, in welcher Spalte unserer Tabelle die ID des Employee-Objekts gespeichert ist.

2.4 Beispiele anfordern

Lassen Sie uns nun einige Beispiele zeigen, wie Hibernate mit solchen verwandten Klassen arbeiten kann.

Szenario eins

Schreiben wir eine Abfrage, um alle Aufgaben herauszufinden, die einem bestimmten Benutzer zugewiesen wurden. So würde diese Abfrage in HQL aussehen:

from EmployeeTask where employee.name = "Ivan Ivanovich"

Sie können einfach durch einen Punkt auf Felder abhängiger Klassen verweisen. Es ist sehr bequem. Aber schreiben wir diese Abfrage trotzdem in Form von Java-Code:


String hql = "from EmployeeTask where employee.name = :username";
Query<EmployeeTask> query = session.createQuery( hql, EmployeeTask.class);
query.setParameter("username", "Ivan Ivanovich");
List<EmployeeTask> resultLIst = query.list();

Szenario zwei

Schreiben wir eine Abfrage, die eine Liste der Mitarbeiter zurückgibt, die überfällige Aufgaben haben. Eine Aufgabe ist überfällig, wenn ihr Termin in der Vergangenheit liegt. So würde diese Abfrage in SQL aussehen:


SELECT DISTINCT employee.*
FROM task JOIN employee ON task.employee_id = employee.id
WHERE task.deadline < CURDATE();

DISTINCTwird verwendet, da einem Benutzer viele Aufgaben zugewiesen werden können.

Und jetzt schreiben wir dieselbe Abfrage in HQL:

select distinct employee from EmployeeTask where deadline < CURDATE();

Employee ist in dieser Abfrage ein Feld der EmployeeTask-Klasse

Situation drei

Weisen Sie dem Direktor alle nicht zugewiesenen Aufgaben zu. Die SQL-Abfrage sieht folgendermaßen aus:


UPDATE task SET employee_id = 4 WHERE employee_id IS NULL

Und jetzt schreiben wir dieselbe Abfrage in HQL:

update EmployeeTask set employee = :user where employee is null

Die letzte Abfrage ist die schwierigste. Wir müssen die ID des Direktors übergeben, aber die EmployeeTask-Klasse enthält kein Feld, in das wir eine ID schreiben können, sondern ein Employee-Feld, in das wir einem Objekt vom Typ Employee eine Referenz zuweisen müssen.


Employee director = session.get(Employee.class, 4);
 
String hql = "update EmployeeTask set employee = :user where employee is null";
Query<EmployeeTask> query = session.createQuery(hql, EmployeeTask.class);
query.setParameter("user", director);
query.executeUpdate();

Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION