【问题标题】:JPQL: How to write dynamic where conditionsJPQL:如何编写动态 where 条件
【发布时间】:2017-05-07 02:57:12
【问题描述】:

我正在与 JPQL 动态 where 条件作斗争。我尝试搜索相同的语法,但找不到。

在我的情况下,如果用户传递 name 参数,那么选择查询应该是

select * from user where name = 'sanjay'

如果用户没有传递名称参数,那么选择查询应该是

select * from user

以下是我的 jpql 查询格式,当 name 参数未传递时失败。

entity_manager.createQuery("select u from user u where u.name = :name").setParameter("name",params[:name]).getResultList()

如何更新上述 JPQL 查询以支持这两种情况,即传递 name 参数和不传递 name 参数时??

【问题讨论】:

  • 使用两个不同的查询,或者如果有参数则附加 where 子句,或者使用条件 API,或者使用 QueryDSL。
  • 以下是动态查询的选项:stackoverflow.com/questions/28874135/…

标签: criteria jpql


【解决方案1】:

这在 JPQL 中是不可能的。你甚至不能做类似的事情

createQuery("select u from user u where u.name = :name OR :name IS NULL")

这是不可能的。就这么简单。使用两个查询或使用 Criteria API

【讨论】:

    【解决方案2】:

    这是我尝试像你一样做一些修改时得到的答案。

    在我的情况下,我的可选参数是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' 的行。

    【讨论】:

      猜你喜欢
      • 2019-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-18
      • 1970-01-01
      • 2021-12-02
      • 2013-07-09
      • 2018-08-14
      相关资源
      最近更新 更多