1. 概要

このチュートリアルでは、非常に便利なJPA機能であるCriteriaQueriesについて説明します。

これにより、生のSQLを実行せずにクエリを記述できるようになるだけでなく、Hibernateの主な機能の1つであるクエリに対するオブジェクト指向の制御が可能になります。 Criteria APIを使用すると、プログラムで基準クエリオブジェクトを構築できます。このオブジェクトでは、さまざまな種類のフィルタリングルールと論理条件を適用できます。

Hibernate 5.2以降、Hibernate Criteria APIは非推奨になり、新しい開発はJPACriteriaAPIに焦点を合わせています。HibernateとJPAを使用してCriteriaクエリを構築する方法について説明します。

2. Mavenの依存関係

APIを説明するために、リファレンスJPA実装Hibernateを使用します。

Hibernateを使用するには、Hibernateの最新バージョンをpom.xmlファイルに追加してください。

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>   
    <version>5.3.2.Final</version>
</dependency>

Hibernateの最新バージョンはここにあります。

3. 基準を使用した簡単な例

基準クエリを使用してデータを取得する方法を確認することから始めましょう。 データベースから特定のクラスのすべてのインスタンスを取得する方法を見ていきます。

データベース内のタプル“ ITEM”を表すItemクラスがあります。

public class Item implements Serializable {

    private Integer itemId;
    private String itemName;
    private String itemDescription;
    private Integer itemPrice;

   // standard setters and getters
}

データベースから「ITEM」のすべての行を取得する単純な条件クエリを見てみましょう。

Session session = HibernateUtil.getHibernateSession();
CriteriaBuilder cb = session.getCriteriaBuilder();
CriteriaQuery<Item> cr = cb.createQuery(Item.class);
Root<Item> root = cr.from(Item.class);
cr.select(root);

Query<Item> query = session.createQuery(cr);
List<Item> results = query.getResultList();

上記のクエリは、すべてのアイテムを取得する方法の簡単なデモンストレーションです。 ステップバイステップで見てみましょう:

  1. SessionFactoryオブジェクトからSessionのインスタンスを作成します
  2. getCriteriaBuilder()メソッドを呼び出して、C riteriaBuilderのインスタンスを作成します
  3. CriteriaBuilder createQuery()メソッドを呼び出して、CriteriaQueryのインスタンスを作成します
  4. Session createQuery()メソッドを呼び出して、Queryのインスタンスを作成します
  5. queryオブジェクトのgetResultList()メソッドを呼び出すと、結果が得られます。

基本を説明したので、基準クエリの機能のいくつかに移りましょう。

3.1. 式の使用

CriteriaBuilderを使用すると、 CriteriaQuery where()メソッドを使用し、CriteriaBuilderによって作成されたExpressionsを提供することにより、特定の条件に基づいてクエリ結果を制限できます。 ]。

一般的に使用されるの例をいくつか見てみましょう。

1000以上の価格のアイテムを入手するには:

cr.select(root).where(cb.gt(root.get("itemPrice"), 1000));

次に、 itemPriceが1000未満のアイテムを取得します。

cr.select(root).where(cb.lt(root.get("itemPrice"), 1000));

itemName を持つアイテムには、Chairが含まれます。

cr.select(root).where(cb.like(root.get("itemName"), "%chair%"));

itemPrice が100〜200のレコード:

cr.select(root).where(cb.between(root.get("itemPrice"), 100, 200));

スケートボードペイント接着剤 itemName が含まれるアイテム:

cr.select(root).where(root.get("itemName").in("Skate Board", "Paint", "Glue"));

指定されたプロパティがnullかどうかを確認するには:

cr.select(root).where(cb.isNull(root.get("itemDescription")));

指定されたプロパティがnullでないかどうかを確認するには:

cr.select(root).where(cb.isNotNull(root.get("itemDescription")));

メソッドisEmpty()および isNotEmpty()を使用して、クラス内のListが空かどうかをテストすることもできます。

さらに、上記の比較の2つ以上を組み合わせることができます。 T Criteria APIを使用すると、式を簡単にチェーンできます

Predicate[] predicates = new Predicate[2];
predicates[0] = cb.isNull(root.get("itemDescription"));
predicates[1] = cb.like(root.get("itemName"), "chair%");
cr.select(root).where(predicates);

論理演算で2つの式を追加するには:

Predicate greaterThanPrice = cb.gt(root.get("itemPrice"), 1000);
Predicate chairItems = cb.like(root.get("itemName"), "Chair%");

論理ORで結合された上記の条件を持つアイテム:

cr.select(root).where(cb.or(greaterThanPrice, chairItems));

論理積で結合された上記の条件に一致するアイテムを取得するには:

cr.select(root).where(cb.and(greaterThanPrice, chairItems));

3.2. 並べ替え

Criteria の基本的な使用法がわかったので、Criteriaの並べ替え機能を見てみましょう。

次の例では、名前の昇順、次に価格の降順でリストを並べ替えます。

cr.orderBy(
  cb.asc(root.get("itemName")), 
  cb.desc(root.get("itemPrice")));

次のセクションでは、集計関数を実行する方法を見ていきます。

3.3. 射影、集計、およびグループ化関数

次に、さまざまな集計関数を見てみましょう。

行数を取得します。

CriteriaQuery<Long> cr = cb.createQuery(Long.class);
Root<Item> root = cr.from(Item.class);
cr.select(cb.count(root));
Query<Long> query = session.createQuery(cr);
List<Long> itemProjected = query.getResultList();

次に、集計関数の例を示します— AverageAggregate関数:

CriteriaQuery<Double> cr = cb.createQuery(Double.class);
Root<Item> root = cr.from(Item.class);
cr.select(cb.avg(root.get("itemPrice")));
Query<Double> query = session.createQuery(cr);
List avgItemPriceList = query.getResultList();

その他の便利な集計メソッドは、 sum() max() min() count()です。 、など。

3.4. CriteriaUpdate

JPA 2.1以降、 CriteriaAPIを使用してデータベース更新を実行するためのサポートがあります。

CriteriaUpdate には、データベースレコードに新しい値を提供するために使用できる set()メソッドがあります。

CriteriaUpdate<Item> criteriaUpdate = cb.createCriteriaUpdate(Item.class);
Root<Item> root = criteriaUpdate.from(Item.class);
criteriaUpdate.set("itemPrice", newPrice);
criteriaUpdate.where(cb.equal(root.get("itemPrice"), oldPrice));

Transaction transaction = session.beginTransaction();
session.createQuery(criteriaUpdate).executeUpdate();
transaction.commit();

上記のスニペットでは、次のインスタンスを作成します CriteriaUpdate から CriteriaBuilder そしてその使用設定() に新しい値を提供する方法 itemPrice 。 複数のプロパティを更新するには、 set()メソッドを複数回呼び出す必要があります。

3.5. CriteriaDelete

CriteriaDelete は、 CriteriaAPIを使用した削除操作を有効にします。

CriteriaDelete のインスタンスを作成し、 where()メソッドを使用して制限を適用する必要があります。

CriteriaDelete<Item> criteriaDelete = cb.createCriteriaDelete(Item.class);
Root<Item> root = criteriaDelete.from(Item.class);
criteriaDelete.where(cb.greaterThan(root.get("itemPrice"), targetPrice));

Transaction transaction = session.beginTransaction();
session.createQuery(criteriaDelete).executeUpdate();
transaction.commit();

4. HQLに対する利点

前のセクションでは、基準クエリの使用方法について説明しました。

明らかに、 HQLに対するCriteriaQueriesの主で最も打撃を与える利点は、すてきでクリーンなオブジェクト指向APIです。

プレーンなHQLと比較して、より柔軟で動的なクエリを簡単に記述できます。 ロジックはIDEでリファクタリングでき、Java言語自体のすべての型安全性の利点があります。

もちろん、特により複雑な結合に関しては、いくつかの欠点もあります。

そのため、通常、作業に最適なツールを使用する必要があります。ほとんどの場合、Criteria APIを使用できますが、下位レベルに移動する必要がある場合もあります。

5. 結論

この記事では、HibernateとJPAの基準クエリの基本と、APIの高度な機能のいくつかに焦点を当てました。

ここで説明するコードは、GitHubリポジトリで入手できます。