3.1 依存エンティティのマッピング
SQL では、JOIN を使用してクエリを作成できます。HQLでも同じことは可能でしょうか?簡単に言うと「はい」です。しかし、完全な答えはもっと興味深いものになるでしょう。
まず、SQL で JOIN を記述する場合、ほとんどの場合、あるテーブルが別のテーブルを参照することを意味します。たとえば、タスク テーブルには、employee テーブルの id 列を参照するemployee_id 列が含まれています。
この依存関係は、Hibernate のアノテーションを使用して説明できます。まず、テーブルのエンティティを作成しましょう。まず、employee テーブルについて説明します。
@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;
}
そして、タスクテーブルのEmployeeTaskクラス:
@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;
}
すべて問題ありませんが、1 つ提案があります。最後の例のemployeeIdフィールドを見てみましょう。
@Column(name="employee_id")
public Integer employeeId;
何か奇妙なことに気づきましたか? そうでない場合は、SQL 言語での考え方がすでに形成されていることを意味します。
問題は、Java 言語では、通常、このような依存関係を少し異なる方法で記述することです。
public Employee employee;
idを指定する必要はありません。通常は、 Employeeオブジェクトへの参照を保持する変数を指定するだけです。または、そのようなオブジェクトが存在しない場合はnullを格納します。
Hibernate では、アノテーションを使用してそのような状況を説明できます。
@ManyToOne
@JoinColumn(name="employee_id", nullable=true)
public Employee employee;
アノテーションは、多くのEmployeeTaskエンティティが 1 つのEmployeeエンティティを参照できること@ManyToOne
を Hibernate に伝えます。
また、アノテーションは、ID の@JoinColumn
取得元となる列の名前を指定します。その他の必要な情報はすべて、Employee クラスの注釈から取得されます。
最終的な結果は次のようになります。
@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 での結合の使用
次に、HQL で関連エンティティへのクエリを記述する方法を見てみましょう。
最初の状況。
従業員 (Employee) がおり、そのタスクのリストを取得したいと考えています。SQL でのクエリは次のようになります。
SELECT task.* FROM task JOIN employee ON task.employee_id = employee.id
WHERE employee.name = "Ivan Ivanovich";
次に、同じクエリを HQL で書いてみましょう。
from EmployeeTask where employee.name = "Ivan Ivanovich"
EmployeeTaskクラスには、 employeeフィールドとnameフィールドがあるため、このクエリは機能します。
状況その2。
期限を過ぎたタスクがある従業員のリストを返します。SQL でのクエリは次のようになります。
SELECT DISTINCT employee.*
FROM task JOIN employee ON task.employee_id = employee.id
WHERE task.deadline < CURDATE();
DISTINCT
1 人のユーザーに多くのタスクを割り当てることができるため、これが使用されます。
次に、同じクエリを HQL で書いてみましょう。
select distinct employee from EmployeeTask where deadline < CURDATE();
このクエリの従業員は、 EmployeeTaskクラスのフィールドです。
状況その3。
割り当てられていないすべてのタスクをディレクターに割り当てます。SQL クエリは次のようになります。
UPDATE task SET employee_id = 4 WHERE employee_id IS NULL
次に、同じクエリを HQL で書いてみましょう。
update EmployeeTask set employee = :user where employee is null
最後のクエリは最も難しいクエリです。ID、director を渡す必要がありますが、EmployeeTask クラスには ID を書き込めるフィールドが含まれておらず、代わりに、Employee 型のオブジェクトへの参照を割り当てる必要がある Employee フィールドが含まれています。
Hibernate では、Query オブジェクトに渡されるクエリ パラメータを利用して、この問題を解決します。また、HQL 自体では、そのようなパラメーターはコロンを通して記述されます: :user
。ただし、これについては少し後で説明します。
GO TO FULL VERSION