1.概要

単一値属性が特定のコレクションのメンバーであるかどうかに基づいてエンティティを照会する必要があるという問題に遭遇することがよくあります。

このチュートリアルでは、https://www.baeldung.com/hibernate-criteria-queries[

Criteria

API]を使用してこの問題を解決する方法を学習します。

2.サンプルエンティティ

私たちが始める前に、私たちの記事で使用するエンティティを見てみましょう。


Department

クラスとhttps://www.baeldung.com/hibernate-one-to-many[many-to-one関係]を持つ

DeptEmployee

クラスがあります。

@Entity
public class DeptEmployee {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private long id;

    private String title;

    @ManyToOne
    private Department department;
}

また、複数の

DeptEmployees

にマップする

Department

エンティティもあります。

@Entity
public class Department {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private long id;

    private String name;

    @OneToMany(mappedBy="department")
    private List<DeptEmployee> employees;
}

3.

CriteriaBuilder.In

まず最初に、

CriteriaBuilder

インターフェースを使用しましょう。 **

in()

メソッドは

Expression

を受け取り、

CriteriaBuilder.In

type

.

の新しい

Predicate

を返します。指定した式が値のリストに含まれているかどうかをテストするために使用できます。

CriteriaQuery<DeptEmployee> criteriaQuery =
  criteriaBuilder.createQuery(DeptEmployee.class);
Root<DeptEmployee> root = criteriaQuery.from(DeptEmployee.class);
In<String> inClause = criteriaBuilder.in(root.get("title"));
for (String title : titles) {
    inClause.value(title);
}
criteriaQuery.select(root).where(inClause);

4. __式

あるいは、https://javaee.github.io/javaee-spec/javadocs/javax/persistence/criteria/Expression.html[

Expression

]インタフェースから、オーバーロードされた

in()

メソッドのセットを使用することもできます。

criteriaQuery.select(root)
  .where(root.get("title")
  .in(titles));


  • CriteriaBuilder.in()

    とは対照的に、

    Expression.in()

    は値のコレクションを受け取ります。

5.副問合せを使用したIN式

これまでは、コレクションを定義済みの値で使用してきました。それでは、コレクションが副照会の出力から派生した場合の例を見てみましょう。

たとえば、

Department、

に属するすべての

__DeptEmployee

__を、指定したキーワードを名前に使用して取得できます。

Subquery<Department> subquery = criteriaQuery.subquery(Department.class);
Root<Department> dept = subquery.from(Department.class);
subquery.select(dept)
  .distinct(true)
  .where(criteriaBuilder.like(dept.get("name"), "%" + searchKey + "%"));

criteriaQuery.select(emp)
  .where(criteriaBuilder.in(emp.get("department")).value(subquery));

ここでは、

Department

エンティティを検索するための式として

value()

に渡されるサブクエリを作成しました。

6.まとめ

このクイック記事では、Criteria APIを使用してIN操作を実現するためのさまざまな方法を学びました。サブクエリでCriteria APIを使用する方法も調べました。

最後に、このチュートリアルの完全な実装はhttps://github.com/eugenp/tutorials/tree/master/persistence-modules/hibernate5[GitHubで入手可能]です。