動的クエリの使用
Liferay の Dynamic Query API は Hibernate の Criteria API をラップします。 テーブルや列ではなく、オブジェクトやメンバー変数の観点から考えるのに役立ちます。 複雑なクエリは、同等のカスタム SQL (または HQL) クエリに比べて、理解しやすく、維持しやすい場合があります。
Liferay 7.4+では、Service Builderエンティティのカスタムクエリを作成するための推奨方法は DSLクエリです。
サンプルをデプロイする
新しいLiferay インスタンスを起動し、以下を実行します。
docker run -it -m 8g -p 8080:8080 liferay/portal:7.4.3.132-ga132
http://localhost:8080でLiferayにサインインします。 メールアドレス test@liferay.com とパスワード testを使用してください。 プロンプトが表示されたら、パスワードを learnに変更します。
次に、次の手順に従って例をデプロイします。
-
liferay-v3r9.zipサンプル プロジェクトをダウンロードして解凍します。curl https://resources.learn.liferay.com/examples/liferay-v3r9.zip -Ounzip liferay-v3r9.zip -
プロジェクトモジュールをビルドしてデプロイします。
cd liferay-v3r9./gradlew deploy -Ddeploy.docker.container.id=$(docker ps -lq)注このコマンドは、デプロイされたjarをDockerコンテナ上の
/opt/liferay/osgi/modulesにコピーするのと同じです。 -
Liferay Dockerコンテナコンソールでデプロイを確認します。
STARTED com.liferay.v3r9.service_1.0.0 [1462] STARTED com.liferay.v3r9.web_1.0.0 [1463] STARTED com.liferay.v3r9.api_1.0.0 [1461] -
サンプル モジュールが動作していることを確認するには、ブラウザーを開いて
https://localhost:8080にアクセスします。 -
V3R9 ポートレットをページに追加します。 サンプル ポートレットは、ウィジェットのサンプルの下にあります。

-
名前と説明を入力してエントリを追加します。 非表示 のチェックを外のままにします。 追加をクリックすると、新しいエントリが V3R9 エントリの下に表示されます。
-
別の名前と説明を持つ別のエントリを追加します。 今回は、 非表示をチェックします。 新しいエントリは V3R9 エントリの下に表示されません。
この例では、動的クエリを使用して、データベース内の指定された値を持つエントリのみを取得します (hidden_ = false)。
動的クエリの作成
V3R9EntryLocalServiceImpl.javaを開きます。 動的クエリのコードは、getV3R9Entriesメソッドで定義されています。
@Override
public List<V3R9Entry> getV3R9Entries(boolean hidden) {
Session session = null;
try {
session = v3r9EntryPersistence.openSession();
DynamicQuery entryQuery = DynamicQueryFactoryUtil.forClass(
V3R9Entry.class, getClass().getClassLoader()
).add(
RestrictionsFactoryUtil.eq("hidden", hidden)
);
return dynamicQuery(entryQuery);
}
catch (Exception exception) {
throw new SystemException(exception);
}
finally {
v3r9EntryPersistence.closeSession(session);
}
}
-
DynamicQueryオブジェクトを作成します。 Hibernate の基準と同様に、Liferay の動的クエリは連鎖可能です。 適切なメソッド呼び出しをクエリ オブジェクトに追加することで、Liferay の動的クエリ オブジェクトに条件を追加したり、予測を設定したり、順序を追加したりできます。 Liferay では、Hibernate セッションから直接基準オブジェクトを作成しません。 代わりに、Liferay のDynamicQueryFactoryUtilを使用して動的クエリ オブジェクトを作成します。 したがって、DynamicQuery entryQuery = DynamicQueryFactoryUtil.forClass(Entry.class, classLoader);の代わりに
Criteria entryCriteria = session.createCriteria(Entry.class); -
次に、適切な制限を追加します。 Hibernate の Criteria API の制限は、SQL クエリの
WHERE句にほぼ対応します。 クエリによって返される結果を制限するためのさまざまな方法を提供します。 この例では、制約を使用して、非表示フィールドに目的の値falseがある結果のみをクエリが返すようにします。 動的クエリに制限を追加するには、Hibernate のRestrictionsクラスを直接呼び出さないでください。 代わりに、すべて同じメソッドを持つRestrictionsFactoryUtilサービスを使用してください:in、between、like、eq、ne、gt、ge、lt、leなど。 したがって、結果を隠し属性が変数隠しの値と一致するエントリに限定するには、次のようにします。entryQuery.add(RestrictionsFactoryUtil.eq("hidden", hidden))の代わりに
entryCriteria.add(Restrictions.eq("hidden", hidden)) -
投影を使用して、クエリによって返される結果の種類を変更します。 たとえば、クエリでエンティティ オブジェクトのリスト (デフォルト) を返さないようにする場合は、特定のエンティティ フィールドの値のリストのみを返すようにクエリに投影を設定できます。 クエリで投影を使用して、エンティティ フィールドの最大値や最小値、フィールドのすべての値の合計、平均などを返すこともできます。 繰り返しますが、Hibernate の
Propertyクラスを通じて直接プロパティを作成しないでください。PropertyFactoryUtilを使用します。entryQuery.setProjection(PropertyFactoryUtil.forName("hidden"));の代わりに
entryCriteria.setProjection(Property.forName("hidden")); -
最後に、クエリが返すリスト内の要素の順序を制御できます。 順序を適用するプロパティと、昇順か降順かを選択します。 このコードは、エンティティの
名前属性によって順序を作成します。 この順序を適用すると、結果はアルファベット順に並べられます。Order order = OrderFactoryUtil.desc("name"); -
動的クエリが完了したら、それを引数として
dynamicQuery()メソッドに渡してクエリを実行します。
return dynamicQuery(entryQuery);
サービスビルダーは、 dynamicQuery() メソッドの複数のオーバーロード定義を生成します。
public List dynamicQuery(DynamicQuery dynamicQuery)public List dynamicQuery(DynamicQuery dynamicQuery, int start, int end)public List dynamicQuery(DynamicQuery dynamicQuery, int start, int end, OrderByComparator orderByComparator)
開始 および 終了 パラメータは、モデル エンティティ インスタンスの範囲の下限と上限です。
動的クエリのその他の使用例
*-service モジュールの外部で Dynamic Query を使用する場合 (たとえば、すぐに使用できる Liferay エンティティの外部で Dynamic Query インスタンスを構築する場合)、Hibernate が参照する -EntityImpl クラスを含むクラス ローダーが必要です。 これを行うには、 -LocalService.dynamicQueryの代わりに DynamicQueryFactoryUtil.forClass メソッドを使用する必要があります。