Tabel layanan

Saiki ayo goleki kasus umum liyane - akeh-kanggo-akeh. Coba bayangake yen kita duwe hubungan akeh-kanggo-akeh antarane tugas lan karyawan :

  • Siji karyawan ing meja pegawe bisa nindakake akeh tugas saka meja tugas.
  • Siji tugas ing meja tugas bisa ditugasake kanggo sawetara karyawan.

Hubungan antarane entitas iki diarani many-to-many. Lan supaya bisa ngleksanakake ing tingkat SQL, kita kudu tabel layanan tambahan. Ayo diarani, contone, employee_task.

Tabel employee_task mung ngemot rong kolom:

  • id_pegawe
  • tugas_id

Saben wektu kita nemtokake tugas tartamtu kanggo pangguna tartamtu, baris anyar bakal ditambahake ing tabel iki. Tuladha:

id_pegawe tugas_id
1 1
1 2
2 3

Inggih, tabel tugas kudu kelangan kolom employee_id . Iku ndadekake pangertèn mung yen tugas mung bisa diutus kanggo siji karyawan. Yen tugas bisa ditugasake kanggo sawetara karyawan, informasi kasebut kudu disimpen ing tabel layanan employee_task .

Hubungan Tabel-Tingkat

Mangkene tampilan tabel anyar kita:

id jeneng pendhudhukan gaji umur join_date
1 Iwan Iwan Programmer 100000 25 30-06-2012
2 Petrov Petruk Programmer 80000 23 2013-08-12
3 Ivanov Sergey Tester 40000 telung puluh 2014-01-01
4 Rabinovich Moisha direktur 200000 35 2015-05-12
5 Kirienko Anastasia Kantor manager 40000 25 10-10-2015
6 Vaska Cat 1000 3 2018-11-11

Tabel karyawan ( ora diganti ) :

Tabel iki nduweni kolom ing ngisor iki:

  • id INT
  • jeneng VARCHAR
  • pendhudhukan VARCHAR
  • gaji INT
  • umur INT
  • join_date DATE

Lan iki kaya tabel tugas , ilang kolom employee_id (ditandhani abang):

id id_karyawan jeneng deadline
1 1 Ndandani bug ing frontend 2022-06-01
2 2 Ndandani bug ing backend 2022-06-15
3 5 Tuku kopi 2022-07-01
4 5 Tuku kopi 2022-08-01
5 5 Tuku kopi 2022-09-01
6 (NULL) Ngresiki kantor (NULL)
7 4 Seneng urip (NULL)
8 6 Seneng urip (NULL)

Tabel iki saiki mung ana 3 kolom:

  • id - nomer tugas unik (lan baris ing tabel)
  • id_pegawe - (dibusak)
  • jeneng - jeneng lan gambaran saka tugas
  • deadline - wektu nganti tugas kudu rampung

Kita uga duwe tabel layanan employee_task , ing ngendi data employee_id wis migrasi saka tabel tugas:

id_pegawe tugas_id
1 1
2 2
5 3
5 4
5 5
(NULL) 6
4 7
6 8

Aku sengaja nyimpen kolom sing wis dibusak ing tabel tugas supaya sampeyan bisa ndeleng manawa data kasebut wis dipindhah menyang tabel employee_task.

Titik penting liyane yaiku garis abang "(NULL) 6" ing tabel employee_task. Aku wis menehi tandha abang amarga ora bakal ana ing tabel employee_task .

Yen tugas 7 ditugasake kanggo pangguna 4, mula kudu ana baris (4, 7) ing tabel employee_task.

Yen tugas 6 ora ditugasake kanggo sapa wae, mula ora ana cathetan ing tabel employee_task. Mangkene versi pungkasan saka tabel kasebut:

meja tugas :

id jeneng deadline
1 Ndandani bug ing frontend 2022-06-01
2 Ndandani bug ing backend 2022-06-15
3 Tuku kopi 2022-07-01
4 Tuku kopi 2022-08-01
5 Tuku kopi 2022-09-01
6 Ngresiki kantor (NULL)
7 Seneng urip (NULL)
8 Seneng urip (NULL)

tabel karyawan_tugas:

id_pegawe tugas_id
1 1
2 2
5 3
5 4
5 5
4 7
6 8

Komunikasi ing tataran kelas Jawa

Nanging kanthi komunikasi ing tingkat Entitas-kelas, kita duwe urutan lengkap. Ayo diwiwiti kanthi kabar apik.

Kaping pisanan, Hibernate duwe anotasi @ManyToMany khusus sing ngidini sampeyan njlèntrèhaké kasus hubungan tabel akeh-kanggo-akeh.

Kapindho, rong kelas Entitas isih cukup kanggo kita. Kita ora butuh kelas kanggo meja layanan.

Mangkene apa kelas kita bakal katon. Kelas Karyawan ing wangun asli:

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

Lan kelas EmployeeTask ing wangun asli:

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

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

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

@ManyToMany anotasi

Aku bakal ngilangi kolom sing ana ing conto, nanging aku bakal nambah sing anyar. Mangkene apa sing bakal katon. Kelas karyawan :

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

   @ManyToMany(cascade = CascadeType.ALL)
   @JoinTable(name="employee_task",
	       joinColumns=  @JoinColumn(name="employee_id", referencedColumnName="id"),
           inverseJoinColumns= @JoinColumn(name="task_id", referencedColumnName="id") )
   private Set<EmployeeTask> tasks = new HashSet<EmployeeTask>();

}

Lan kelas EmployeeTask :

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

   @ManyToMany(cascade = CascadeType.ALL)
   @JoinTable(name="employee_task",
       	joinColumns=  @JoinColumn(name="task_id", referencedColumnName="id"),
       	inverseJoinColumns= @JoinColumn(name=" employee_id", referencedColumnName="id") )
   private Set<Employee> employees = new HashSet<Employee>();

}

Iku misale jek sing kabeh rumit, nanging nyatane kabeh iku prasaja.

Pisanan, nggunakake anotasi @JoinTable (ora bakal bingung karo @JoinColumn), sing nggambarake tabel layanan employee_task.

Kapindho, nerangake yen kolom task_id saka tabel employee_task nuduhake kolom id saka tabel tugas.

Katelu, ujar manawa kolom employee_id saka tabel employee_task nuduhake kolom id saka tabel karyawan.

Nyatane, kanthi bantuan anotasi, kita njlèntrèhaké data apa sing ana ing tabel employee_task lan carane Hibernate kudu napsirake.

Nanging saiki kita bisa kanthi gampang nambah (lan mbusak) tugas kanggo karyawan. Lan uga nambah pemain apa wae kanggo tugas apa wae.

Nyuwun conto

Ayo nulis sawetara pitakon sing menarik kanggo luwih ngerti cara kerja lapangan ManyToMany iki. Lan padha bisa persis kaya samesthine.

Kaping pisanan, kode lawas kita bakal bisa digunakake tanpa owah-owahan, amarga direktur duwe lapangan tugas sadurunge:

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

Kapindho, yen kita pengin nemtokake pemain liyane kanggo sawetara tugas, mula luwih gampang nindakake iki:

Employee director = session.find(Employee.class, 4);
EmployeeTask task = session.find(EmployeeTask.class, 101);
task.employees.add(director);

session.update(task);
session.flush();

Penting! Minangka asil saka nglakokaké panjalukan iki, ora mung tugas bakal duwe eksekutor-direktur, nanging uga direktur bakal duwe tugas No.

Kaping pisanan, kasunyatan babagan hubungan antarane direktur lan tugas ing tabel employee_task bakal disimpen minangka senar: (4,101).

Kapindho, kolom sing ditandhani karo @ManyToMany anotasi minangka obyek proxy, lan nalika diakses, query database tansah dieksekusi.

Dadi, yen sampeyan nambahake tugas menyang karyawan lan nyimpen informasi babagan karyawan menyang database, banjur sawise tugas kasebut bakal duwe pelaksana anyar ing dhaptar pelaksana.