如何使用 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(*) 列

java-jpa-criteriaBuilder使用入门

JPA / Hibernate:CriteriaBuilder - 如何使用关系对象创建查询?

如何使 CriteriaBuilder 加入自定义“开启”条件?

JPA CriteriaBuilder - 如何使用“IN”比较运算符

如何通过两个字段加入(CriteriaBuilder)