@ManyToOne

Ledig

2.1 Sammenkædning på tabelniveau

Vi har set, hvordan Hibernate opbevarer samlinger i hjælpetabeller. Lad os nu finde ud af, hvordan man organiserer relationer mellem fuldgyldige tabeller, der gemmer rigtige Entity-klasser.

Der er fire typer relationer mellem enhedsklasser i Hibernate:

  • en -til- en
  • en til mange
  • mange -til- en
  • mange -til- mange

Og vi starter analysen med den enkleste mulighed - mange -til- en .

Du er allerede stødt på et sådant forhold mellem tabeller i SQL. Sådan ser det normalt ud:

id navn beskæftigelse løn alder join_date
1 Ivanov Ivan Programmer 100.000 25 2012-06-30
2 Petrov Petr Programmer 80.000 23 2013-08-12
3 Ivanov Sergey Tester 40.000 tredive 2014-01-01
4 Rabinovich Moisha Direktør 200.000 35 2015-05-12
5 Kirienko Anastasia Kontorchef 40.000 25 2015-10-10
6 Vaska Kat 1000 3 2018-11-11

medarbejder tabel:

Denne tabel har følgende kolonner:

  • id INT
  • navn VARCHAR
  • erhverv VARCHAR
  • løn INT
  • alder INT
  • join_date DATE

Og sådan ser opgavetabellen , som indeholder opgaver for medarbejdere, ud:

id Medarbejder-ID navn deadline
1 1 Ret en fejl på frontend 2022-06-01
2 2 Ret en fejl på backend 2022-06-15
3 5 Køb kaffe 2022-07-01
4 5 Køb kaffe 2022-08-01
5 5 Køb kaffe 2022-09-01
6 (NUL) Ryd op på kontoret (NUL)
7 4 Nyd livet (NUL)
8 6 Nyd livet (NUL)

Denne tabel har kun 4 kolonner:

  • id – unikt opgavenummer (og rækker i tabellen);
  • medarbejder-id – medarbejder-id fra medarbejdertabellen, som opgaven er tildelt;
  • navn – navn og beskrivelse af opgaven;
  • deadline - det tidspunkt, hvor opgaven skal være afsluttet.

Vi ser, at mange rækker i opgavetabellen kan referere til en enkelt post i medarbejdertabellen. Sådan en relation på tabelniveau kaldes mange-til -en.

2.2 Forholdet til Java-klasseniveauet

Ud over kommunikation på tabelniveau kan du også organisere kommunikation på niveau med enhedsklasser i Hibernate. Dette gøres med en anmærkning @ManyToOne.

Men først, lad os lige oprette to klasser: Employee og 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;
}

Og en anden klasse til at opbevare medarbejderjob:

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

Alt er godt med disse klasser, men der er ingen sammenhæng mellem dem, der ville afspejle det faktum, at feltet medarbejder-id i klassen EmployeeTask refererer til id-feltet i klassen Employee. Det er tid til at ordne det

2.3 @ManyToOne annotation.

For det første er vi i Java vant til at operere på objekter (og objektreferencer) i stedet for deres id. Så lad os først og fremmest i stedet for feltet medarbejderId i EmployeeTask-klassen pege på et objekt af typen Employee. Sådan kommer vores nye klasse til at se ud:

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

Ved hjælp af annotationen @ManyToOne har vi indikeret, at mange EmployeeTask-objekter kan henvise til ét objekt af typen Employee. Ved hjælp af annoteringen har vi også @JoinColumnangivet, i hvilken kolonne i vores tabel id'et for Employee-objektet er gemt.

2.4 Eksempler på anmodning

Og lad os nu vise nogle eksempler på, hvordan Hibernate kan arbejde med sådanne relaterede klasser.

Scenarie et

Lad os skrive en forespørgsel for at finde ud af alle de opgaver, der er blevet tildelt en bestemt bruger. Sådan ser denne forespørgsel ud i HQL:

from EmployeeTask where employee.name = "Ivan Ivanovich"

Du kan blot henvise til felter af afhængige klasser gennem en prik. Det er meget behageligt. Men lad os stadig skrive denne forespørgsel i form af Java-kode:

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

Scenarie to

Lad os skrive en forespørgsel, der returnerer en liste over medarbejdere, der har forfaldne opgaver. En opgave er forsinket, hvis dens deadline ligger i fortiden. Sådan ser den forespørgsel ud i SQL:

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

DISTINCTbruges, fordi der kan være mange opgaver tildelt én bruger.

Og lad os nu skrive den samme forespørgsel i HQL:

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

Medarbejder i denne forespørgsel er et felt i klassen EmployeeTask

Situation tre

Tildel alle ikke-tildelte opgaver til direktøren. SQL-forespørgslen vil se sådan ud:


UPDATE task SET employee_id = 4 WHERE employee_id IS NULL

Og lad os nu skrive den samme forespørgsel i HQL:

update EmployeeTask set employee = :user where employee is null

Den sidste forespørgsel er den sværeste. Vi skal videregive direktørens ID, men EmployeeTask-klassen indeholder ikke et felt, hvor vi kan skrive et id, i stedet indeholder det et Employee-felt, hvor vi skal tildele en reference til et objekt af typen 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();
Kommentarer
  • Populær
  • Ny
  • Gammel
Du skal være logget ind for at skrive en kommentar
Denne side har ingen kommentarer endnu