Java 博士后及;JPA命名查询-其中的任意(*)值
我想为一些特定的GET案例编写过滤器查询 我现在做的是为每个案例编写单独的查询,这相当耗时。相反,我想编写一个大的命名查询,如果设置了过滤器,我可以在where子句中输入一个值,否则任何值都可以。JPA可以这样做吗? 这是一个示例控制器,它通过特定的客户端ID返回付款:Java 博士后及;JPA命名查询-其中的任意(*)值,java,postgresql,jpa,orm,named-query,Java,Postgresql,Jpa,Orm,Named Query,我想为一些特定的GET案例编写过滤器查询 我现在做的是为每个案例编写单独的查询,这相当耗时。相反,我想编写一个大的命名查询,如果设置了过滤器,我可以在where子句中输入一个值,否则任何值都可以。JPA可以这样做吗? 这是一个示例控制器,它通过特定的客户端ID返回付款: public List<PaymentEntity> findAllByClientId(final int page, final int pageSize, final String fromDate,
public List<PaymentEntity> findAllByClientId(final int page, final int pageSize, final String fromDate,
final String toDate, final Long clientId) {
Map<String, Object> parameters = new HashMap<>();
parameters.put("clientId", clientId);
return super.findWithNamedQueryPagination("PaymentEntity.findAllWithPaginationByClientId", parameters,
PaymentEntity.class, page, pageSize, fromDate, toDate);
}
我现在希望能够传递如下参数:
if(clientId == null) {
parameters.put("clientId", "*");
} else {
parameters.put("clientId", clientId);
}
但是现在我当然得到了一个类型错误:参数值[*]与预期的类型[java.lang.Long(n/a)]不匹配。
实现这一目标的最佳方式是什么?我是否必须编写本机查询,或者是否有方法处理命名查询
编辑以澄清:上面的示例显示了一个类型为
Long
的查询,但我也需要使用String
执行此操作。您可以尝试更改查询,如:
WHERE (i.clientContractData.client.id = :clientId or :clientId = -1)
注:我认为JPA中的参考文献有2个层次,这里有3个层次:
i.clientContractData.client.id
您可能需要在此处使用额外的显式联接您可以尝试更改查询,如:
WHERE (i.clientContractData.client.id = :clientId or :clientId = -1)
注:我认为JPA中的参考文献有2个层次,这里有3个层次:
i.clientContractData.client.id
您可能需要在此处使用额外的显式联接更新的查询
SELECT i FROM PaymentEntity i WHERE
((i.clientContractData.client.id = :clientId and :clientId IS NOT NULL)
or (i.clientContractData.client.id IS NOT NULL AND :clientId IS NULL))
AND i.createdAt BETWEEN :fromDate AND :toDate ORDER BY i.createdAt DESC
如果clientId为null,则发送null值:
if(clientId == null) {
parameters.put("clientId", null);
} else {
parameters.put("clientId", clientId);
}
对于更复杂的情况,可以使用rsql jpa规范项目:
更新的查询
SELECT i FROM PaymentEntity i WHERE
((i.clientContractData.client.id = :clientId and :clientId IS NOT NULL)
or (i.clientContractData.client.id IS NOT NULL AND :clientId IS NULL))
AND i.createdAt BETWEEN :fromDate AND :toDate ORDER BY i.createdAt DESC
如果clientId为null,则发送null值:
if(clientId == null) {
parameters.put("clientId", null);
} else {
parameters.put("clientId", clientId);
}
对于更复杂的情况,可以使用rsql jpa规范项目:
你的意思是
:clientId为null
?我想这取决于OP来决定使用什么作为任何值我编辑了这个问题。对于Long类型,这是一个很好的解决方案,但不幸的是,我需要一个同样适用于字符串的解决方案。对于级别-它使用的是3个级别:)我为这种情况编写了一些测试。在WHERE子句和OR语句的组合中,3个级别的深度引用似乎确实是一个问题。当我将客户端存储在付款中并按此方式操作时,它会工作:从PaymentEntity I中选择I,其中(:clientId为NULL或I.client.id=:clientId)和i.createdAt介于:fromDate和:toDate之间i.createdAt DESC的顺序
您的意思是:clientId为null
?我想应该由OP决定使用什么作为任何值我编辑了这个问题。对于Long类型,这是一个很好的解决方案,但不幸的是,我需要一个同样适用于字符串的解决方案。对于级别-它使用的是3个级别:)我为这种情况编写了一些测试。在WHERE子句和OR语句的组合中,3个级别的深度引用似乎确实是一个问题。当我将客户端存储在付款中并按此方式操作时:从PaymentEntity I中选择I,其中(:clientId为NULL或I.client.id=:clientId)和I.createdAt介于:fromDate和:toDate之间,按I.createdAt DESC进行排序
这看起来是一个很好的长字符串解决方案,我今天将尝试一下,然后返回给您!虽然当我有很多值要过滤时,查询会变得相当长:)不幸的是,这只会在PaymentEntity
也有相关clientContractData
的情况下给出结果,但默认情况下我需要所有条目。实际上,我不明白为什么这不起作用:从PaymentEntity I中选择I,其中(:clientId为NULL或I.clientContractData.client.id=:clientId)和I.createdAt介于:fromDate和:toDate ORDER BY I.createdAt DESC
。这只返回带有clientcontractdata的付款。也许这是因为@Maciej Kowalski提到的3层深嵌套?这看起来是long&string的一个很好的解决方案,我今天会尝试一下,然后给你回复!虽然当我有很多值要过滤时,查询会变得相当长:)不幸的是,这只会在PaymentEntity
也有相关clientContractData
的情况下给出结果,但默认情况下我需要所有条目。实际上,我不明白为什么这不起作用:从PaymentEntity I中选择I,其中(:clientId为NULL或I.clientContractData.client.id=:clientId)和I.createdAt介于:fromDate和:toDate ORDER BY I.createdAt DESC
。这只返回带有clientcontractdata的付款。也许这是因为@Maciej Kowalski提到的三层深嵌套?