处理空参数值的JPA查询

处理空参数值的JPA查询,jpa,Jpa,我是JPA新手,这里是我的一个查询,我有两个参数作为查询的一部分,任何参数都可以是空值 @Query(value = "SELECT ord.purchaseOrderNumber,ord.salesOrderNumber,ord.quoteNumber" + " FROM Order ord WHERE ord.purchaseOrderNumber LIKE :poNumber% " + " AND ord.salesOrderNumber

我是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进行过滤,那么如何避免这种情况呢?

不幸的是,=比较不适用于NULL值,因为您有一个谓词是NULL,不是NULL。这意味着当quoteNumber为空和不为空时,需要进行不同的查询。您可以在java代码中检查null,然后选择要调用的正确查询。 如果订单、报价编号不能为空字符串(“”)(它们不应为空),则可以将缺少给定编号表示为空字符串,并始终使用正常比较。请记住,要将DB模式设置为列不能为null,默认值为“”。
顺便说一句,您的列名建议使用数字,但您使用的是字符串比较,我希望可以。

您可以使用类似的方法 :quoteNumber=-999和ord.quoteNumber=:quoteNumber

如果要传递null,请将-999传递给查询


我想看看是否可以使用@parma将其默认为-999。您可以添加一组条件来“忽略”具有空值或空字符串的属性

e、 g


对于可为空的参数,可以执行以下操作:

@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) "

我们可以通过使用@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);
我们发现两个名为“D”的客户忽略了他们的电子邮件

生成的JPQL WHERE子句如下所示:

其中(?为null或customer0_u0.name=?)和(?为null或customer0_0.email=?)
使用此方法,我们信任数据库服务器,以识别关于查询参数为null的子句,并优化查询的执行计划,从而使其不会产生显著的性能开销。对于某些查询或数据库服务器,特别是涉及大型表扫描的查询或数据库服务器,可能会产生性能开销。

奇怪的是,当我使用pgAdmin时,这种方法在本机sql中有效,但JPA中的本机sql不支持这种方法,例如:select*from table where(:queryParam为NULL或:queryParam=table.column1)。提供了另一种使用JpaRepository规范的方法[相关:此答案看起来是复制粘贴而来的。当您重复使用其他人的作品时,请给予赞扬…感谢@fbastien提供如此有见地的评论,是的,它来自baeldung分享,旨在帮助他人寻找所发布问题的解决方案
@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);
List<Customer> customers = repository.findCustomerByNameAndEmail("D", null);
 
assertEquals(2, customers.size());