Spring Dataで直SQLクエリかつ設定されていないパラメータを無視する方法
背景
Spring Dataで直SQLクエリを使って検索するときに、設定していない検索パラメータ(配列)を無視したいときの対応メモです。
対応
以下のような例の場合、categoriesが文字列配列の値が入っているとき、「:#{#conditions.categories}) IS NULL」と書くとSQLシンタックスに合わない("hoge", "foo" IS NULL)。
※値を設定していないときはNULLなので、この文法でもいけてしまうのがやらしい。
※配列ではない「from」はそのまま書ける。
なので、以下のようにCOALESCE関数をかませて、SQLのシンタックスに合うようにする。
@Query(value = "SELECT e " + "FROM EventDto e " + "WHERE 1 = 1 " + " AND ( :#{#conditions.from} IS NULL OR :#{#conditions.from} <= e.from) " + " AND ( COALESCE(:#{#conditions.categories}) IS NULL OR ec.eventCategory IN ( :#{#conditions.categories} ) )" ) public Page<EventDto> findByConditions(@Param("conditions") EventSearchCondition condition, Pageable page);
@Data public class EventSearchCondition { private List<EventCategoryEnum> categories; private LocalDateTime from; }
まとめ
もしかたら直SQLでなくてもSpring Dataの関数記法でも行けるのかもしれない(´・ω・`)