背景
今回のプロジェクトではJPQLを使用し、SQLとは記載方法が異なる為メモとして纏める。
JPQLとは
JavaPersistenceQueryLanuage
JPAでエンティティからデータを取得する際に利用されるクエリ言語であり、データベーステーブルではなくエンティティクラスとそのフィールドに対して動作する。
利用する為に
「META-INF/persistence.xml」に、クエリが定義されたファイルとマッピングするエンティティを記載する。
<mapping-file>META-INF/orm.xml</mapping-file>
<class>com.example.model.Person</class>
基本構文
1つのテーブルを取得する場合
orm.xml
<named-query name="findAllPersons">
<query>SELECT
p
FROM
Person p
</query>
</named-query>
xxx.java
List<Person> persons = entityManager.createNamedQuery("findAllPersons", Person.class);
※createNamedQueryの第一引数にはxmlファイルに定義したクエリ名、第二引数には戻り値の型を指定する。
複数のテーブルを取得する場合
orm.xml
<named-query name="findPersonsAddressInfo">
<query>SELECT
p, a
FROM
Person p
INNER JOIN
Address a
ON
p.addressId = a.addressId
</query>
</named-query>
xxx.java
List<Object> personsAddressInfo = entityManager.createNamedQuery("findPersonsAddressInfo", Object.class);
for (Object obj : personsAddressInfo) {
Object[] objs = (Object[]) obj;
//キャストを行うことでゲッター等が使用できる
Person person = (Person) objs[0]
System.out.println(person.getFamilyName());
Address address = (Address) objs[1]
System.out.println(address.getPostalCode());
}
※配列の順番はSELECT文の順番となり、異なるとキャストエラーが発生する。
条件を指定する場合
orm.xml
<named-query name="findPerson">
<query>SELECT
p
FROM
Person p
WHERE
p.familyName = :familyName
</query>
</named-query>
xxx.java
List<Person> person = entityManager.createNamedQuery("findPerson", Person.class).setParameter("familyName", "テスト");
※setParameterの第一引数と同じ名称の、xmlに記載した「:familyName」には、setParameterの第二引数である「テスト」が入る。
INSERT文
JPQLではINSERT文を使用せず、代わりに「persist」と「flush」を使用する。
xxx.java
EntityManager em = ...;
EntityTransaction transaction = em.getTransaction();
// トランザクションの開始
transaction.begin();
// 登録するデータをエンティティに設定する
Person person = new Person();
person.setFamilyName("John");
// エンティティをDBに登録する
em.persist(person);
// 変更を同期する
em.flush();
// トランザクションのコミット
transaction.commit();