Relația la nivel de masă

Să ne uităm din nou la cele două tabele noastre:

id Nume ocupaţie salariu vârstă Data înscrierii
1 Ivanov Ivan Programator 100000 25 30-06-2012
2 Petrov Petr Programator 80000 23 12-08-2013
3 Ivanov Serghei Tester 40000 treizeci 01-01-2014
4 Rabinovici Moisha Director 200000 35 2015-05-12
5 Kirienko Anastasia Manager de birou 40000 25 2015-10-10
6 Vaska Pisică 1000 3 2018-11-11

masa angajatului:

Acest tabel are următoarele coloane:

  • id INT
  • nume VARCHAR
  • ocupatie VARCHA
  • salariu INT
  • vârsta INT
  • join_date DATE

Și așa arată tabelul de sarcini , care conține sarcini pentru angajați:

id Emploee_id Nume Termen limită
1 1 Remediați o eroare pe front-end 2022-06-01
2 2 Remediați o eroare pe backend 2022-06-15
3 5 Cumpără cafea 2022-07-01
4 5 Cumpără cafea 2022-08-01
5 5 Cumpără cafea 2022-09-01
6 (NUL) Curățați biroul (NUL)
7 4 Bucură-te de viață (NUL)
8 6 Bucură-te de viață (NUL)

Acest tabel are doar 4 coloane:

  • id este numărul unic al sarcinii (și rândurile din tabel).
  • employee_id - ID-ul angajatului din tabelul de angajați căruia îi este atribuită sarcina.
  • nume - numele și descrierea sarcinii.
  • termen - timpul până la care sarcina trebuie finalizată.

O singură intrare din tabelul de angajați poate fi referită de mai multe rânduri din tabelul de sarcini. O astfel de relație la nivel de tabel se numește unu-la -mulți.

Relația cu nivelul clasei Java

Și clasele noastre, clasa Angajați :

@Entity
@Table(name="user")
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;
}

Și clasa EmployeeTask în forma sa originală:

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

Adnotare @OneToMany

Putem aranja comunicarea între clasele de Entități într-un mod diferit.

Vă amintiți adnotarea @ElementCollection pe care am folosit-o pentru a crea o colecție de obiecte copil în clasa părinte? Ceva similar se poate face cu adnotarea @OneToMany . Numai de această dată, clasa de Angajați va fi schimbată :

@Entity
@Table(name="user")
class Employee {
   @Column(name="id")
   public Integer id;

   @OneToMany(cascade = CascadeType.ALL)
   @JoinColumn(name = "employee_id")
   private Set<EmployeeTask> tasks = new HashSet<EmployeeTask>();
}

Folosind adnotarea @OneToMany , am indicat că obiectulangajatpoate stoca multe obiecte EmployeeTask . De asemenea, folosind adnotarea @JoinColumn , am indicat în ce coloană a tabelului de activități este stocat id-ul obiectuluiangajat.

Cu toate acestea, clasa EmployeeTask nu conține de obicei un câmp care se referă la coloana employee_id. Exemplu:

@Entity
@Table(name="task")
class EmployeeTask {
   @Column(name="id")
   public Integer id;

   @Column(name="name")
   public String description;

   @Column(name="deadline")
   public Date deadline;
}

Câmpul employee_id este considerat un câmp de serviciu și valoarea acestuia este controlată de Hibernate.

Cere exemple

Dacă doriți să adăugați o sarcină unui lucrător, atunci trebuie să scrieți cod astfel:

EmployeeTask task1 = new EmployeeTask();
task1.description = "Do Something Important";
session.persist(task1);

EmployeeTask task2 = new EmployeeTask();
task2.description = "Nothing to do";
session.persist(task2);
session.flush();

Employee director = session.find(Employee.class, 4);
director.tasks.add(task1);
director.tasks.add(task2);

session.update(director);
session.flush();

Mai întâi, creăm două obiecte EmployeeTask , le salvăm în baza de date și apelăm metoda flush() astfel încât operația INSERT să fie efectuată și obiectele să aibă ID-uri.

Apoi îl găsim pe director în baza de date, luăm câmpul de sarcini de la el și îi adăugăm două sarcini. Apoi salvăm directorul în baza de date. După aceea, valoarea 4 va apărea în baza de date pentru sarcini noi în coloana employee_id - id-ul directorului din tabelul angajat.

Important! Tabelele din baza de date sunt aceleași pentru adnotările @ManyToOne și @OneToMany . Dar clasele Java pentru aceste tabele sunt diferite.