JavaPersistenceQueryLanguage(JPQL)は、JavaPersistenceAPI(JPA)で使用するクエリ言語です。
本記事では、JPQLとは何かといった概要的な情報から初心者向けに基本となる設定方法をサンプルコードを掲載しながらご紹介していきます。
目次
JavaPersistenceQueryLanguageとは?
JavaPersistenceQueryLanuage(JPQL)は、JPAでエンティティからデータを取得する際に利用されるクエリ言語です。
SQL文と記述方法は似ていますが、JPQLの場合は取得対象をデータベースのテーブルではなく、エンティティを指定することになります。
WikipediaのJPAのページを確認してみると下記のように説明されています。
Java Persistence Query Language (JPQL) は、関係データベースに格納されたエンティティに対するクエリに使用される。文法的にはSQLに似ているが、データベースの表を直接操作するのではなく、エンティティオブジェクトを操作する。
引用元: Wikipedia
JPQLの基本構文
JPQLはSQLの記述方法と似ていると記載しましたが、実際にどのように記述することになるのか確認しておきましょう。
SELECT フィールド名 FROM エンティティ名 [WHERE 条件式]
JPQLで全てのフィールドを取得する
SQLの書き方と異なる点に全カラム(全フィールド)取得の方法が挙げられます。
SQLでは「*」を記述することで、対象行に存在するカラムのデータを全て取得出来ましたが、JPQLではエイリアスを指定する必要があります。
SELECT A FROM Person A
この場合Personというエンティティのエイリアスが「A」となり、SELECT句にエイリアス名を指定することで全てのフィールドの値を取得することが出来ます。
JPQLをJavaプログラムで使ってみる
JPQLの概要と基本的な構文を説明しましたが、JPQLをJavaプログラムから利用するための設定方法についても確認しておく必要あります。
順を追って説明していきます。
今回は各種開発環境の設定が完了して、JPAプロジェクトを作成できた段階を想定してご紹介します。
今回利用するデータベースには「fruits」というテーブル名で下記のデータを用意しておきました。
+------+-----------+ | id | name | +------+-----------+ | 1 | りんご | | 2 | みかん | | 3 | ぶどう | +------+-----------+
エンティティクラス生成
まずは今回利用する「fruits」テーブルのエンティティクラスを作成していきます。
プロジェクトを右クリックから「JPAツール」→「テーブルからエンティティを生成」を選択します。
接続しているデータベースのテーブル一覧が表示されますので、エンティティを作成したいクラスを選択し、チェックを入れて「次へ」をクリックします。
キージェネレーターには「identity」を選択しておきました。
確認画面が表示されるので完了しておきます。
するとsrcフォルダの配下にパッケージが作成され、下記のようなエンティティクラスが生成されます。
package jpa_sample; import java.io.Serializable; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.NamedQuery; /** * The persistent class for the fruits database table. * */ @Entity @NamedQuery(name="Fruits.findAll", query="SELECT f FROM Fruits f") public class Fruits implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private int id; private String name; public Fruits() { } public int getId() { return this.id; } public void setId(int id) { this.id = id; } public String getName() { return this.name; } public void setName(String name) { this.name = name; } }
DBへの接続情報を追記
JPAのプロジェクト作成時に生成されたMETA-INFフォルダ配下の「persistence.xml」を確認してみると現時点でこのような記述になっているかと思います。
<?xml version="1.0" encoding="UTF-8"?> <persistence version="2.2" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd"> <persistence-unit name="jpa_sample"> <class>jpa_sample.Fruits</class> </persistence-unit> </persistence>
ここに接続したDB情報を追記します。
<?xml version="1.0" encoding="UTF-8"?> <persistence version="2.2" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd"> <persistence-unit name="jpa_sample"> <class>jpa_sample.Fruits</class> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"></property> <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"></property> <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/データベース名"></property> <property name="hibernate.connection.username" value="ユーザー名"></property> <property name="hibernate.connection.password" value="パスワード"></property> </properties> </persistence-unit> </persistence>
これでデータベースとの接続が出来る状態となりました。
プログラムからアクセスしてみよう
では上記で作成したエンティティクラスに、JavaのMainクラスからアクセスしてデータを取得してみましょう。
package jpa_sample; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; import javax.persistence.TypedQuery; public class Main { public static void main(String[] args) { EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpa_sample"); EntityManager em = emf.createEntityManager(); TypedQuery findAllQuery = em.createNamedQuery("Fruits.findAll", Fruits.class); for(int ii = 0; ii < findAllQuery.getResultList().size(); ii++) { Fruits fruit = findAllQuery.getResultList().get(ii); System.out.println("ID:" + fruit.getId() + ", Name:" + fruit.getName()); } } }
実行結果
ID:1, Name:りんご ID:2, Name:みかん ID:3, Name:ぶどう
Fuitsエンティティに定義した「findAll」のJPQL文が実行され、テーブルに格納された全データをエンティティクラスへのアクセスで取得出来ていることが分かります。
サンプルコード解説
JPQLの関連した記述部分を確認しておきましょう。
エンティティクラス
エンティティクラスの17行目に記載された下記のコードがデータ取得時のJPQL文を定義している場所です。
@NamedQuery(name="Fruits.findAll", query="SELECT f FROM Fruits f")
呼び出し元クラス
MainクラスからJPQL文を呼び出しているのが下記の記述です。
TypedQuery findAllQuery = em.createNamedQuery("Fruits.findAll", Fruits.class);
createNamedQueryでエンティティクラスに設定したJPQL文の名前「findAll」を実行するように指定しています。
例えばこの記述を次のように変更すれば、「id」が「1」のデータだけを取得することが出来るようになります。
エンティティクラス
@NamedQuery(name="Fruits.findById", query="SELECT f FROM Fruits f WHERE f.id = 1")
呼び出し元クラス
TypedQuery findAllQuery = em.createNamedQuery("Fruits.findById", Fruits.class);
さいごに:JavaPersistenceQueryLanguageでエンティティでのクエリ操作を試してみよう
本記事では、JavaPersistenceQueryLanguage(JPQL)の概要と実際に利用するまでの設定方法を含めてサンプルコードを掲載しながらご紹介してきました。
今回の内容は基本的な設定方法をご紹介したに過ぎず、JPQLの記述方法は多岐に渡ります。
設定さえ出来てしまえば、あとは各種JPQL文を試していくだけですので、各種JPQLの記述方法を試しながらエンティティでのクエリ操作にチャレンジしてみてください。
サンプルではJPAプロジェクトの設定にEclipseのHibernate Toolsというプラグインを利用しています。