3.1 Bağımlı varlıkları eşleme

SQL'de JOIN kullanarak sorgu yazabilirsiniz. Aynısını HQL'de yapmak mümkün mü? Kısa cevap evet. Ancak tam cevap daha ilginç olacak.

İlk olarak, SQL'de bir JOIN yazdığımızda, bu genellikle bir tablonun başka bir tabloya atıfta bulunduğu anlamına gelir. Örneğin, görev tablosu, çalışan tablosunun kimlik sütununa atıfta bulunan bir çalışan_kimliği sütunu içerir.

Bu bağımlılık, Hazırda Bekletme modundaki ek açıklamalar kullanılarak açıklanabilir. Öncelikle tablolarımız için Entities oluşturalım. Öncelikle çalışan tablosunu tanımlayalım:

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

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

   @Column(name="salary")
   public Integer salary;

   @Column(name="join_date")
   public Date joinDate;
}

Ve görev tablosu için EmployeeTask sınıfı :

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

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

   @Column(name="employee_id")
   public Integer employeeId;

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

Her şey yolunda ama bir öneri var. Son örnekte çalışanId alanına bakalım :

@Column(name="employee_id")
public Integer employeeId;

Garip bir şey fark ettin mi? Değilse, bu, SQL dilinde zaten bir düşünme biçimi oluşturduğunuz anlamına gelir.

Mesele şu ki, Java dilinde böyle bir bağımlılığı genellikle biraz farklı tanımlarız:

public Employee employee;

Bir id belirtmemize gerek yoktur , genellikle sadece Çalışan nesnesine bir referans tutan bir değişken belirtiriz . Veya böyle bir nesne yoksa null değerini saklar.

Ve Hibernate, ek açıklamaları kullanarak böyle bir durumu tanımlamamıza izin verir:

@ManyToOne
@JoinColumn(name="employee_id", nullable=true)
public Employee employee;

Açıklama, @ManyToOneHibernate'e birçok ÇalışanGörevi varlığının bir Çalışan varlığına başvurabileceğini söyler .

Ek açıklama, kimliğin@JoinColumn alınacağı sütunun adını belirtir . Diğer tüm gerekli bilgiler, Çalışan sınıfının açıklamalarından alınacaktır.

Nihai sonuç şöyle görünecektir:

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

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

   @ManyToOne
   @JoinColumn(name="employee_id", nullable=true)
   public Employee employee;

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

3.2 HQL'de birleştirmenin kullanılması

Şimdi HQL'de ilgili varlıklara nasıl sorgu yazılacağına bakalım.

İlk durum.

Bir çalışanımız (Çalışan) var ve onun görevlerinin bir listesini almak istiyoruz. İşte bu sorgunun SQL'de nasıl görüneceği:

SELECT task.* FROM task JOIN employee ON task.employee_id = employee.id
WHERE employee.name = "Ivan Ivanovich";

Şimdi aynı sorguyu HQL'de yazalım:

from EmployeeTask where employee.name = "Ivan Ivanovich"

EmployeeTask sınıfının bir çalışan alanı ve bir ad alanı vardır , bu nedenle bu sorgu çalışacaktır.

Durum iki.

Gecikmiş görevleri olan çalışanların bir listesini döndürün. İşte bu sorgunun SQL'de nasıl görüneceği:

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

DISTINCTBir kullanıcıya atanan birçok görev olabileceği için kullanılır.

Şimdi aynı sorguyu HQL'de yazalım:

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

Bu sorgudaki çalışan , EmployeeTask sınıfının bir alanıdır

Durum üç.

Atanmamış tüm görevleri yöneticiye atayın. SQL sorgusu şöyle görünecektir:

UPDATE task SET employee_id = 4 WHERE employee_id IS NULL

Şimdi aynı sorguyu HQL'de yazalım:

update EmployeeTask set employee = :user where employee is null

Son sorgu en zor olanıdır. ID, directörü geçmemiz gerekiyor fakat EmployeeTask sınıfı id yazabileceğiniz bir alan değil, bunun yerine Employee tipinde bir nesneye referans atamanız gereken bir Çalışan alanı içeriyor.

Hibernate'de bu sorun, Query nesnesine iletilen sorgu parametrelerinin yardımıyla çözülür. Ve HQL'nin kendisinde, bu tür parametreler iki nokta üst üste ile yazılır: :user. Ama bunun hakkında biraz sonra konuşacağız.