处理 NULL 参数值的 JPA 查询
Posted
技术标签:
【中文标题】处理 NULL 参数值的 JPA 查询【英文标题】:JPA Query to handle NULL parameter value 【发布时间】:2021-06-27 17:41:24 【问题描述】:我是 JPA 的新手,这是我的查询之一,我有几个参数作为查询的一部分,任何参数都可以是空值
@Query(value = "SELECT ord.purchaseOrderNumber,ord.salesOrderNumber,ord.quoteNumber"
+ " FROM Order ord WHERE ord.purchaseOrderNumber LIKE :poNumber% "
+ " AND ord.salesOrderNumber LIKE :soNumber "
+ " AND ord.quoteNumber = :quoteNumber "
如果我的输入参数:quoteNumber 为 NULL,那么我不应该按 ord.quoteNumber = NULL 过滤,那么如何避免这种情况
【问题讨论】:
提供了另一种使用 JpaRepository 规范的方法 [***.com/a/61948111/3440284] 相关:***.com/questions/28874135/… 【参考方案1】:您可以添加一组条件来“忽略”具有空值或空字符串的属性。
例如
+ " AND (ord.quoteNumber = :quoteNumber or :quoteNumber is null or :quoteNumber = '' ")
【讨论】:
【参考方案2】:不幸的是,= 比较不适用于空值,因为您有谓词 IS NULL,IS NOT NULL。这意味着当您 quoteNumber 为 null 而不是时,您需要对案例进行不同的查询。您可以在 java 代码中检查 null,然后选择要调用的正确查询。 如果 oder,报价编号不能是空字符串 ("")(它们不应该),那么您可以将缺少给定数字表示为空字符串并始终使用正常比较。只需记住将您的数据库架构设置为列不能为空,并且它们的默认值为“”。 顺便说一句,您的列名建议使用数字,但您使用的是字符串比较,我希望没问题。
【讨论】:
奇怪的是,当我 pgAdmin 时这在本机 sql 中有效,但 JPA 中的本机 sql 不支持这一点,例如:select * from table where (:queryParam IS NULL or :queryParam=table.第 1 列)。【参考方案3】:对于可为空的参数,您可以执行以下操作:
@Query(value = "SELECT ord.purchaseOrderNumber,ord.salesOrderNumber,ord.quoteNumber"
+ " FROM Order ord "
+ " WHERE (:poNumber is NULL OR ord.purchaseOrderNumber LIKE :poNumber)"
+ " AND (:soNumberis NULL OR ord.salesOrderNumber LIKE :soNumber)"
+ " AND (:quoteNumber is NULL OR ord.quoteNumber = :quoteNumber) "
【讨论】:
我试过这个 - 没有“LIKE”但用“=”代替它总是返回一个空数组。【参考方案4】:我们可以通过使用@Query 注解并在 JPQL 语句中添加一个小复杂性来避免创建额外的方法:
@Query("SELECT c FROM Customer c WHERE (:name is null or c.name = :name) and (:email is null"
+ " or c.email = :email)")
List<Customer> findCustomerByNameAndEmail(@Param("name") String name, @Param("email") String email);
注意如果:email 参数为空:
:email is null or s.email = :email
那么该子句始终为真,因此不会影响整个 WHERE 子句。
让我们确保它有效:
List<Customer> customers = repository.findCustomerByNameAndEmail("D", null);
assertEquals(2, customers.size());
我们发现两个名字是“D”的客户忽略了他们的电子邮件。
生成的 JPQL WHERE 子句如下所示:
其中 (? 为 null 或 customer0_.name=?) 和 (? 为 null 或 customer0_.email=?) 使用这种方法,我们信任数据库服务器以识别关于我们的查询参数为空的子句并优化查询的执行计划,使其不会产生显着的性能开销。对于某些查询或数据库服务器,尤其是涉及大量表扫描的情况,可能会产生性能开销。
【讨论】:
这个答案看起来是从https://www.baeldung.com/spring-data-jpa-null-parameters 复制粘贴的。当您重复使用他人的工作时,请给予学分... 感谢 @fbastien 提供如此有见地的评论,是的,这是来自 baeldung 的分享,旨在帮助寻求解决问题的人【参考方案5】:如果你想检查参数是否为空或空值,你应该这样做:
@Query("SELECT t FROM Test t WHERE (t.parameterOne = :parameterOne OR ((:parameterOne IS NULL) OR (:parameterOne = ''))");
请注意,如果 parameterOne 为 null 或为空,则该子句始终为真,因此不会影响整个 WHERE 子句。
【讨论】:
【参考方案6】:如果null
是有效参数,
... AND ((:param is null and param is null) or (:param is not null and param = :param)) AND ...
【讨论】:
【参考方案7】:你可以使用这样的东西 :quoteNumber = -999 AND ord.quoteNumber = :quoteNumber
当你想传递 null 时,将 -999 传递给查询。
我正在尝试查看是否可以使用 @parma 将其默认为 -999
【讨论】:
以上是关于处理 NULL 参数值的 JPA 查询的主要内容,如果未能解决你的问题,请参考以下文章