这是我尝试像你一样做一些修改时得到的答案。
在我的情况下,我的可选参数是List<String>,解决方案如下:
@Query(value = "SELECT *
FROM ...
WHERE (COLUMN_X IN :categories OR COALESCE(:categories, null) IS NULL)"
, nativeQuery = true)
List<Archive> findByCustomCriteria1(@Param("categories") List<String> categories);
这边:
- 如果参数 有一个或多个值它被的左侧选中>OR 运算符
- 如果 parameter categories 为 null,这意味着我必须为 选择所有值COLUMN_X,将始终在 OR 运算符的右侧返回 TRUE
为什么是 COALESCE 以及为什么里面有一个 null 值?
让我们在所有条件下探索WHERE 子句:
案例一: categories = null
(COLUMN_X IN null OR COALESCE(null, null) IS NULL)
OR的左边部分会返回false,而OR的右边部分会一直返回true,其实COALESCE会返回第一个非如果存在 null 值,如果所有参数都为 null,则返回 null。
案例2:categories = ()
(COLUMN_X IN null OR COALESCE(null, null) IS NULL)
JPA 会自动将空列表识别为空值,因此与案例 1 的结果相同。
案例3: categories = ('ONE_VALUE')
(COLUMN_X IN ('ONE_VALUE') OR COALESCE('ONE_VALUE', null) IS NULL)
OR 的左侧部分仅对 COLUMN_X = 'ONE_VALUE' 的那些值返回 true,而 OR 的右侧部分永远不会返回 true,因为它是等于'ONE_VALUE' IS NULL(即为假)。
为什么将 null 作为第二个参数?嗯,那是因为COALESCE 至少需要两个参数。
案例4: categories = ('ONE_VALUE', 'TWO_VALUE')
(COLUMN_X IN ('ONE_VALUE', 'TWO_VALUE') OR COALESCE('ONE_VALUE', 'TWO_VALUE', null) IS NULL)
与案例 3 一样,OR 运算符的左侧部分将仅选择 COLUMN_X 等于 'ONE_VALUE' 或 'TWO_VALUE' 的行。