如何使用 CriteriaBuilder 的多个 JOIN 来构建 Predicate?
Posted
技术标签:
【中文标题】如何使用 CriteriaBuilder 的多个 JOIN 来构建 Predicate?【英文标题】:How to use multiple JOINs with CriteriaBuilder to build Predicate? 【发布时间】:2021-02-11 13:13:18 【问题描述】:我有一个表 A,它的属性是表 B 中的一个实体,该实体又连接到表 C。
(工作的)SQL 查询如下所示:
SELECT a.* from A a
LEFT JOIN B b ON a.b_id=b.id
LEFT JOIN C c ON b.c_id=c.id where c.attribute=VALUE;
基本上 VALUE 是我过滤的内容。 A->B 是一对一的关系,B->C 是一对一的关系。
还有其他参数我也在过滤,所以我有一个Specification
类,它为传入的每个参数生成一个Predicate
,以构建一个谓词列表,然后在最后将它们与在一起。 Specification
正在从我的Repository
调用,使用类似findAll(MySpecificationClass.search(params))
的东西。
我很难理解如何在我的 Specification
类中使用 CriteriaBuilder
编写此 SQL 查询。
注意事项:
-
这是在用 Kotlin 编写的 Spring Boot 应用程序中。
我的规范类是单例的,所以我不能自动装配
EntityManager
。
我尝试使用 get()
s 链从 A 导航到 B 到 C 但这不起作用 - 无论如何它似乎都会返回所有记录。
我的项目使用的是 spring-data-jpa 2.2.6
【问题讨论】:
is this question helpful? 不确定您的意思 - 我正在尝试解决问题,但在任何文档、示例或博客文章中都没有找到任何有用的答案。只有某些类型的问题是“允许的”吗? 这是另一个 SO 问题的链接。我认为你的问题很好。 哦,对了,对不起,我误解了 :-) 我今天早些时候读过,并阅读了那里链接的一些页面。我没有使用在那里和链接文档中提到的 Metamodel API。我也不能使用在许多示例中使用的 EntityManager。在我看来,Criteria API 只是没有很好的文档记录并且难以理解。 【参考方案1】:通过一位同事的帮助,我能够构建这个(也应该是 INNER JOINS)。
我的Specification
类返回的具体谓词是:
val joinToB: Join<A, B> = root.join("B", JoinType.INNER)
val joinToC: Join<B, C> = joinToB.join("C", JoinType.INNER)
cb.equal(joinToC.get<Long>("attribute"), VALUE)
【讨论】:
以上是关于如何使用 CriteriaBuilder 的多个 JOIN 来构建 Predicate?的主要内容,如果未能解决你的问题,请参考以下文章
使用 CriteriaBuilder 的 JPA 计数(*)。如何使用 CriteriaBuilder 检索 count(*) 列
JPA / Hibernate:CriteriaBuilder - 如何使用关系对象创建查询?
如何使 CriteriaBuilder 加入自定义“开启”条件?