@ManyToOne

Disponibile

2.1 Collegamento a livello di tabella

Abbiamo visto come Hibernate memorizza le raccolte in tabelle ausiliarie. Ora scopriamo come organizzare le relazioni tra tabelle a tutti gli effetti che memorizzano le classi Entity reali.

Esistono quattro tipi di relazioni tra le classi Entity in Hibernate:

  • uno a uno
  • uno a molti
  • molti -a- uno
  • molti - a - molti

E inizieremo l'analisi con l'opzione più semplice: molti a uno .

Hai già riscontrato una tale relazione tra le tabelle in SQL. Ecco come appare di solito:

id nome occupazione stipendio età data di iscrizione
1 Ivanov Ivan Programmatore 100000 25 2012-06-30
2 Petrov Petr Programmatore 80000 23 2013-08-12
3 Sergej Ivanov Tester 40000 trenta 2014-01-01
4 Rabinovich Moisha Direttore 200000 35 2015-05-12
5 Kirienko Anastasia Capo ufficio 40000 25 2015-10-10
6 Vasca Gatto 1000 3 2018-11-11

tabella dei dipendenti:

Questa tabella ha le seguenti colonne:

  • id INT
  • nome VARCHAR
  • occupazione VARCHAR
  • stipendio INT
  • età INT
  • join_date DATE

Ed ecco come appare la tabella delle attività , che contiene le attività per i dipendenti:

id ID Dipendente nome scadenza
1 1 Risolto un bug sul frontend 2022-06-01
2 2 Risolto un bug sul backend 2022-06-15
3 5 Compra il caffè 2022-07-01
4 5 Compra il caffè 2022-08-01
5 5 Compra il caffè 2022-09-01
6 (NULLO) Pulisci l'ufficio (NULLO)
7 4 Goditi la vita (NULLO)
8 6 Goditi la vita (NULLO)

Questa tabella ha solo 4 colonne:

  • id – numero univoco dell'attività (e righe nella tabella);
  • employee_id – ID dipendente dalla tabella dei dipendenti a cui è assegnata l'attività;
  • name – nome e descrizione dell'attività;
  • scadenza - il tempo entro il quale l'attività deve essere completata.

Vediamo che molte righe nella tabella delle attività possono fare riferimento a una singola voce nella tabella dei dipendenti. Tale relazione a livello di tabella è chiamata molti-a -uno.

2.2 Relazione con il livello di classe Java

Oltre alla comunicazione a livello di tabella, puoi anche organizzare la comunicazione a livello di classi di entità in Hibernate. Questo viene fatto con un'annotazione @ManyToOne.

Ma prima, creiamo solo due classi: Employee e 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;
}

E una seconda classe per archiviare i lavori dei dipendenti:

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

Tutto va bene con queste classi, ma non c'è alcuna relazione tra loro che rifletta il fatto che il campo employeeId della classe EmployeeTask fa riferimento al campo id della classe Employee. È ora di aggiustarlo

2.3 Annotazione @ManyToOne.

Innanzitutto, in Java siamo abituati a operare su oggetti (e riferimenti a oggetti) piuttosto che sul loro id. Quindi prima di tutto, invece del campo employeeId nella classe EmployeeTask, puntiamo semplicemente a un oggetto di tipo Employee. Ecco come sarà la nostra nuova classe:

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

Con l'aiuto dell'annotazione @ManyToOne , abbiamo indicato che molti oggetti EmployeeTask possono fare riferimento a un oggetto di tipo Employee. Inoltre, utilizzando l'annotazione @JoinColumn , abbiamo indicato in quale colonna della nostra tabella è memorizzato l'id dell'oggetto Employee.

2.4 Richiedi esempi

E ora mostriamo alcuni esempi di come Hibernate può lavorare con tali classi correlate.

Scenario uno

Scriviamo una query per scoprire tutte le attività che sono state assegnate a un utente specifico. Ecco come apparirebbe questa query in HQL:

from EmployeeTask where employee.name = "Ivan Ivanovich"

Puoi semplicemente fare riferimento ai campi delle classi dipendenti attraverso un punto. È molto comodo. Ma scriviamo ancora questa query sotto forma di codice Java:

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 due

Scriviamo una query che restituisca un elenco di dipendenti con attività scadute. Un'attività è scaduta se la sua scadenza è nel passato. Ecco come sarebbe quella query in SQL:

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

DISTINCTviene utilizzato perché possono essere assegnate molte attività a un utente.

E ora scriviamo la stessa query in HQL:

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

Il dipendente in questa query è un campo della classe EmployeeTask

Situazione tre

Assegna tutte le attività non assegnate al direttore. La query SQL sarà simile a questa:


UPDATE task SET employee_id = 4 WHERE employee_id IS NULL

E ora scriviamo la stessa query in HQL:

update EmployeeTask set employee = :user where employee is null

L'ultima domanda è la più difficile. Dobbiamo passare l'ID del direttore, ma la classe EmployeeTask non contiene un campo in cui possiamo scrivere un id, invece contiene un campo Employee in cui dobbiamo assegnare un riferimento a un oggetto di tipo 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();
Commenti
  • Popolari
  • Nuovi
  • Vecchi
Devi avere effettuato l'accesso per lasciare un commento
Questa pagina non ha ancora commenti