@ManyToOne

All lectures for NL purposes
Niveau 1 , Les 848
Beschikbaar

2.1 Koppelen op tafelniveau

We hebben gezien hoe Hibernate collecties opslaat in hulptabellen. Laten we nu eens kijken hoe we relaties kunnen organiseren tussen volwaardige tabellen waarin echte Entity-klassen zijn opgeslagen.

Er zijn vier soorten relaties tussen Entity-klassen in Hibernate:

  • een -op- een
  • een -op- veel
  • veel -op- een
  • veel -op- veel

En we beginnen de analyse met de eenvoudigste optie - veel -op- een .

Zo'n relatie tussen tabellen ben je al eens tegengekomen in SQL. Zo ziet het er meestal uit:

ID kaart naam bezigheid salaris leeftijd join_date
1 Ivanov Ivan Programmeur 100000 25 2012-06-30
2 Petrov Petr Programmeur 80000 23 2013-08-12
3 Ivanov Sergej Tester 40000 dertig 01-01-2014
4 Rabinovich Moisha Regisseur 200000 35 2015-05-12
5 Kirienko Anastasia Officemanager 40000 25 2015-10-10
6 Vaska Kat 1000 3 2018-11-11

werknemers tafel:

Deze tabel heeft de volgende kolommen:

  • id INT
  • naam VARCHAR
  • bezetting VARCHAR
  • salaris INT
  • leeftijd INT
  • join_date DATUM

En zo ziet de takentabel , die taken voor medewerkers bevat, er uit:

ID kaart medewerker_id naam deadline
1 1 Los een bug op de frontend op 01-06-2022
2 2 Los een bug op de backend op 2022-06-15
3 5 Koop koffie 01-07-2022
4 5 Koop koffie 01-08-2022
5 5 Koop koffie 01-09-2022
6 (NUL) Ruim het kantoor op (NUL)
7 4 Geniet van het leven (NUL)
8 6 Geniet van het leven (NUL)

Deze tabel heeft slechts 4 kolommen:

  • id – uniek taaknummer (en rijen in de tabel);
  • employee_id – werknemer-ID van de werknemerstabel waaraan de taak is toegewezen;
  • naam – naam en omschrijving van de taak;
  • deadline - de tijd waarop de taak moet zijn voltooid.

We zien dat veel rijen in de takentabel kunnen verwijzen naar een enkel item in de werknemerstabel. Zo'n relatie op tabelniveau wordt veel-op -een genoemd.

2.2 Relatie met het Java-klasseniveau

Naast communicatie op tafelniveau kun je in Hibernate ook communicatie organiseren op het niveau van Entity-klassen. Dit gebeurt met een annotatie @ManyToOne.

Maar laten we eerst twee klassen maken: Employee en 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;
}

En een tweede klasse om banen van werknemers op te slaan:


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

Alles is goed met deze klassen, maar er is geen relatie tussen hen die zou weerspiegelen dat het veld employeeId van de klasse EmployeeTask verwijst naar het veld id van de klasse Employee. Het is tijd om het te repareren

2.3 @ManyToOne-annotatie.

Ten eerste zijn we in Java gewend om op objecten (en objectreferenties) te werken in plaats van op hun id. Laten we dus allereerst in plaats van het veld employeeId in de klasse EmployeeTask, een object van het type Employee aanwijzen. Zo ziet onze nieuwe klas eruit:


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

Met behulp van de annotatie @ManyToOne hebben we aangegeven dat veel EmployeeTask-objecten kunnen verwijzen naar één object van het type Employee. Ook hebben we met behulp van de annotatie aangegeven in welke kolom van onze tabel de id van het Employee-object is opgeslagen. @JoinColumn

2.4 Vraag voorbeelden aan

En laten we nu enkele voorbeelden laten zien van hoe Hibernate met dergelijke verwante klassen kan werken.

Scenario één

Laten we een query schrijven om alle taken te achterhalen die aan een specifieke gebruiker zijn toegewezen. Hier is hoe deze query eruit zou zien in HQL:

from EmployeeTask where employee.name = "Ivan Ivanovich"

U kunt eenvoudig verwijzen naar velden van afhankelijke klassen door middel van een punt. Het is zeer comfortabel. Maar laten we deze query nog steeds schrijven in de vorm van 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();

Scenario twee

Laten we een query schrijven die een lijst retourneert van werknemers die achterstallige taken hebben. Een taak is achterstallig als de deadline in het verleden ligt. Dit is hoe die query eruit zou zien in SQL:


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

DISTINCTwordt gebruikt omdat er veel taken aan één gebruiker kunnen worden toegewezen.

En laten we nu dezelfde query in HQL schrijven:

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

Werknemer in deze query is een veld van de klasse EmployeeTask

Situatie drie

Wijs alle niet-toegewezen taken toe aan de directeur. De SQL-query ziet er als volgt uit:


UPDATE task SET employee_id = 4 WHERE employee_id IS NULL

En laten we nu dezelfde query in HQL schrijven:

update EmployeeTask set employee = :user where employee is null

De laatste vraag is de moeilijkste. We moeten de ID van de directeur doorgeven, maar de klasse EmployeeTask bevat geen veld waarin we een id kunnen schrijven, maar bevat een veld Employee waarin we een verwijzing moeten toewijzen aan een object van het type Employee.


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();

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