3.1 KartlÀggning av beroende enheter
I SQL kan du skriva frĂ„gor med JOIN. Ăr det möjligt att göra samma sak i HQL? Det korta svaret Ă€r ja. Men det fullstĂ€ndiga svaret blir mer intressant.
För det första, nÀr vi skriver en JOIN i SQL betyder det oftast att en tabell refererar till en annan tabell. Till exempel innehÄller uppgiftstabellen en anstÀlld_id-kolumn som hÀnvisar till id-kolumnen i anstÀlldtabellen.
Detta beroende kan beskrivas med anteckningar i Hibernate. LÄt oss först skapa entiteter för vÄra tabeller. LÄt oss först beskriva personaltabellen:
@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;
}
Och EmployeeTask -klassen för uppgiftstabellen :
@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;
}
Allt Àr bra, men det finns ett förslag. LÄt oss titta pÄ fÀltet anstÀlld-ID i det sista exemplet:
@Column(name="employee_id")
public Integer employeeId;
MÀrker du nÄgot konstigt? Om inte, sÄ betyder det att du redan har bildat ett sÀtt att tÀnka i SQL-sprÄket.
Saken Àr den att i Java-sprÄket brukar vi beskriva ett sÄdant beroende lite annorlunda:
public Employee employee;
Vi behöver inte ange ett id , vi brukar bara specificera en variabel som innehÄller en referens till Employee -objektet . Eller lagrar null om det inte finns nÄgot sÄdant objekt.
Och Hibernate lÄter oss beskriva en sÄdan situation med hjÀlp av kommentarer:
@ManyToOne
@JoinColumn(name="employee_id", nullable=true)
public Employee employee;
Anteckningen @ManyToOne
talar om för Hibernate att mÄnga EmployeeTask- enheter kan hÀnvisa till en Employee- enhet .
Och anteckningen @JoinColumn
anger namnet pÄ den kolumn som id:t kommer ifrÄn . All annan nödvÀndig information kommer att hÀmtas frÄn anteckningarna för klassen AnstÀlld.
Det slutliga resultatet kommer att se ut sÄ hÀr:
@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 AnvÀnda join i HQL
Och lÄt oss nu titta pÄ hur man skriver frÄgor till relaterade enheter i HQL.
Första situationen.
Vi har en anstÀlld (AnstÀlld) och vi vill fÄ en lista över hans arbetsuppgifter. SÄ hÀr skulle den frÄgan se ut i SQL:
SELECT task.* FROM task JOIN employee ON task.employee_id = employee.id
WHERE employee.name = "Ivan Ivanovich";
Och lÄt oss nu skriva samma frÄga i HQL:
from EmployeeTask where employee.name = "Ivan Ivanovich"
Klassen EmployeeTask har ett anstÀlldsfÀlt och det har ett namnfÀlt , sÄ den hÀr frÄgan kommer att fungera.
Situation tvÄ.
Returnera en lista över anstÀllda som har försenade uppgifter. SÄ hÀr skulle den frÄgan se ut i SQL:
SELECT DISTINCT employee.*
FROM task JOIN employee ON task.employee_id = employee.id
WHERE task.deadline < CURDATE();
DISTINCT
anvÀnds eftersom det kan vara mÄnga uppgifter tilldelade en anvÀndare.
Och lÄt oss nu skriva samma frÄga i HQL:
select distinct employee from EmployeeTask where deadline < CURDATE();
anstÀlld i den hÀr frÄgan Àr ett fÀlt i klassen EmployeeTask
Situation tre.
Tilldela alla otilldelade uppgifter till regissören. SQL-frÄgan kommer att se ut sÄ hÀr:
UPDATE task SET employee_id = 4 WHERE employee_id IS NULL
Och lÄt oss nu skriva samma frÄga i HQL:
update EmployeeTask set employee = :user where employee is null
Den sista frÄgan Àr den svÄraste. Vi mÄste skicka ID:t, director, men EmployeeTask-klassen innehÄller inte ett fÀlt dÀr du kan skriva id, istÀllet innehÄller den ett Employee-fÀlt dÀr du behöver tilldela en referens till ett objekt av typen Employee.
I Hibernate löses detta problem med hjÀlp av frÄgeparametrar som skickas till Query-objektet. Och i sjÀlva HQL skrivs sÄdana parametrar genom ett kolon: :user
. Men vi kommer att prata om detta lite senare.
GO TO FULL VERSION