使用 Spring 规范编写复杂的 SQL 查询
Posted
技术标签:
【中文标题】使用 Spring 规范编写复杂的 SQL 查询【英文标题】:Writing Complex SQL Queries Using Spring Specificaitons 【发布时间】:2021-11-10 08:26:51 【问题描述】:我有一个复杂的 SQL 查询,我想在我的 Spring Boot 应用程序中执行它。以下是它的 JPQL 等价物的一部分:
SELECT j FROM Job j WHERE
( (?6 = 0L) OR
0L IN (SELECT i12.filterFieldId FROM IjpPublishFilterFields i12 WHERE i12.jobId = j.id AND i12.fieldType LIKE 'GRADE') OR
(?6 IN (SELECT node.id FROM Grade node
INNER JOIN Grade parent ON ((node.lft BETWEEN parent.lft AND parent.rgt) AND
parent.id IN (SELECT i1.filterFieldId FROM IjpPublishFilterFields i1 WHERE **j.id** = i1.jobId AND i1.fieldType LIKE 'GRADE'))
WHERE node.organizationId = ?5 AND
node.isActive = true AND
parent.isActive = true )))
由于还有多个其他条件需要动态形成 'Where' 子句,我相信 @Query
注释不在窗口中。
经过大量研究,我仍然无法将此 where 子句转换为规范。
例如,我可以返回整个 IjpPublishFilterFields
对象,但不能只返回 i12.filterFieldId
。
如何使用 JPA 规范编写 where 子句?
【问题讨论】:
【参考方案1】:我能够通过使用EnitityManager.createQuery()
来解决这个问题,并使用简单的字符串连接形成了这个等效的 JPQL。我仍然相信,我们应该能够使用 Spring data JPA Specifications
形成这个 where
caluse。因此,欢迎提供进一步的提示。
【讨论】:
【参考方案2】:您的查询没有什么特别之处,因此您应该能够将其翻译成类似criteriaBuilder.or( criteriaBuilder.eq(param, 0L), criteriaBuilder.literal(0L).in(subquery1), param.in(subquery2) )
的内容,其中subquery1
和subquery2
的构造大致如下:Subquery<Long> subquery1 = criteriaQuery.subquery(Long.class); Root<IjpPublishFilterFields> r = subquery1.from(IjpPublishFilterFields.class); subquery1.select(r.get("filterFieldId")); ...
【讨论】:
以上是关于使用 Spring 规范编写复杂的 SQL 查询的主要内容,如果未能解决你的问题,请参考以下文章