SpringのCriteriaBuilderでdisjunctionメソッドを使った条件付きクエリ作成方法を解説
生徒
「Springで、複数の条件のどれにも該当しないデータを簡単に検索する方法はありますか?」
先生
「SpringのCriteriaBuilderクラスにはdisjunctionメソッドがあります。このメソッドを使えば、初期状態で常にfalseの条件を作成でき、動的に条件を追加していくことができます。」
生徒
「具体的にdisjunctionメソッドの使い方を教えてください!」
先生
「それでは、disjunctionメソッドを使ったクエリ作成方法を解説しますね!」
1. CriteriaBuilderとは?
CriteriaBuilderは、SpringのJPAを使って動的なクエリを作成するためのクラスです。これを利用すると、SQLを直接記述することなく、Javaコードで柔軟なクエリを構築することが可能です。
特に、動的に条件を組み合わせる必要がある場合や、複雑な検索ロジックを求められるシナリオで重宝します。disjunctionメソッドは、初期状態でfalse条件を作成するため、条件を後から追加する場合に便利です。
2. disjunctionメソッドとは?
CriteriaBuilderのdisjunctionメソッドは、初期状態でfalseの条件を作成するためのメソッドです。これを利用すると、条件を後から追加する際に柔軟な対応が可能となります。
例えば、「価格が100以下、またはカテゴリが『食品』以外の商品を検索する」といったケースで使用されます。条件が追加されるまではfalseとなり、条件が追加されるとそれらが評価される形になります。
3. 実際のコード例
以下は、価格が100以下またはカテゴリが『食品』以外の商品を検索する例です。
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Predicate;
import jakarta.persistence.criteria.Root;
import org.springframework.stereotype.Repository;
import org.springframework.beans.factory.annotation.Autowired;
import jakarta.persistence.EntityManager;
@Repository
public class ProductRepository {
@Autowired
private EntityManager entityManager;
public List<Product> findProductsByDynamicConditions(Double maxPrice, String excludedCategory) {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Product> query = cb.createQuery(Product.class);
Root<Product> root = query.from(Product.class);
Predicate predicate = cb.disjunction();
if (maxPrice != null) {
predicate = cb.or(predicate, cb.lessThanOrEqualTo(root.get("price"), maxPrice));
}
if (excludedCategory != null) {
predicate = cb.or(predicate, cb.not(cb.equal(root.get("category"), excludedCategory)));
}
query.select(root).where(predicate);
return entityManager.createQuery(query).getResultList();
}
}
このコードのポイント:
disjunctionメソッドを使用して初期状態の条件を作成している点。- 条件が動的に追加されるため、柔軟なクエリ作成が可能である点。
- 動的な検索要件に対応するための効率的なアプローチである点。
4. 実行結果例
データベースに以下のデータがある場合:
ID | 商品名 | 価格 | カテゴリ
1 | 商品A | 120 | 食品
2 | 商品B | 90 | 電化製品
3 | 商品C | 80 | 食品
例えば、「価格が100以下、またはカテゴリが『食品』以外」の商品を検索すると、結果は以下の通りです:
商品B, 商品C
5. 応用:複数条件を組み合わせたdisjunctionメソッドの活用
disjunctionメソッドは、他の条件メソッドと組み合わせて柔軟なクエリを作成することが可能です。例えば、「価格が100以下、またはカテゴリが『食品』以外、または在庫が50以上の商品」を検索する場合、以下のように記述します。
query.where(
cb.or(
cb.lessThanOrEqualTo(root.get("price"), 100),
cb.not(cb.equal(root.get("category"), "食品")),
cb.greaterThanOrEqualTo(root.get("stock"), 50)
)
);
このように、disjunctionメソッドを使用することで、柔軟なクエリ作成が可能となり、さまざまな要件に対応できます。
6.まとめ
この記事では、SpringのCriteriaBuilderクラスを使用したdisjunctionメソッドについて解説しました。このメソッドは、初期状態でfalseの条件を作成し、動的に条件を追加して柔軟なクエリを構築するのに役立ちます。
例えば、「価格が100以下、またはカテゴリが『食品』以外」のような条件を簡単に設定でき、実際のプロジェクトで多様な検索条件を効率的に取り扱うことが可能です。また、他の条件メソッドと組み合わせることで、さらに複雑なクエリも作成できるため、幅広いニーズに応えられる強力なツールです。
以下に、応用例として「価格が100以下、またはカテゴリが『食品』以外、または在庫が50以上の商品」を検索するサンプルコードを掲載します。
query.where(
cb.or(
cb.lessThanOrEqualTo(root.get("price"), 100),
cb.not(cb.equal(root.get("category"), "食品")),
cb.greaterThanOrEqualTo(root.get("stock"), 50)
)
);
このように、disjunctionメソッドを活用すれば、複雑な検索条件を簡単に作成し、実際の開発現場で効率的なデータ検索を行うことができます。
生徒
「disjunctionメソッドを使った条件付きクエリ作成方法がよく分かりました!初期状態をfalseにしておけば、条件を後から追加できるのが便利ですね。」
先生
「そうですね。disjunctionメソッドは、動的なクエリを作る上で非常に柔軟性が高い方法です。他にもandやorメソッドと組み合わせると、さらに複雑な条件を簡単に扱えるようになりますよ。」
生徒
「次は、複数条件を組み合わせたクエリを試してみたいと思います!」
先生
「いいですね!実際にコードを書いてみると、理解がさらに深まるはずです。困ったことがあれば、また質問してくださいね。」