是否可以将连接到子选择的查询转换为 JPQL?
Is it possible to transform a query joining onto a subselect into JPQL?
给定以下本机 SQL 查询包含到子选择的连接,是否有办法将其转换为 JPQL 查询(或者,是否可以使用 @SqlResultSetMapping
来映射此查询我不必执行数千个后续查询来填充我的对象(比如在这种情况下,Foo
包含对单个 Bar
的引用和 Baz
实体的列表):
SELECT
foo.*, bar.*, baz.*
FROM
foo
INNER JOIN
bar ON foo.bar_id = bar.id
INNER JOIN
baz ON bar.baz_id = baz.id
INNER JOIN
(SELECT
bar_id, MAX(some_int) ct
FROM
foo
WHERE
some_int <= 2
GROUP BY bar_id) max_id ON max_id.bar_id = foo.bar_id
WHERE
foo.some_int = max_id.ct;
不能直接使用 JPQL,但您可以在 Hibernate 之上使用 Blaze-Persistence 来执行此操作。请参阅以下示例:https://persistence.blazebit.com/documentation/1.5/core/manual/en_US/#subquery-in-from-clause
我在这里假设使用 JPA 模型作为示例。您将需要以下 CTE 实体。
@CTE
@Entity
public class MyMaxEntity {
@Id Integer id;
Integer someInt;
}
这是查询
criteriaBuilderFactory.create(entityManager, Foo.class, "foo")
.fetch("bar.baz")
.innerJoinOnSubquery(MyMaxEntity.class, "maxEnt")
.from(Foo.class, "subFoo")
.bind("id").select("subFoo.id")
.bind("value").select("MAX(subFoo.someInt)")
.where("subFoo.someInt").le(2)
.end()
.on("maxEnt.id").eqExpression("foo.bar.id")
.end()
.where("foo.someInt").eqExpression("maxEnt.value")
给定以下本机 SQL 查询包含到子选择的连接,是否有办法将其转换为 JPQL 查询(或者,是否可以使用 @SqlResultSetMapping
来映射此查询我不必执行数千个后续查询来填充我的对象(比如在这种情况下,Foo
包含对单个 Bar
的引用和 Baz
实体的列表):
SELECT
foo.*, bar.*, baz.*
FROM
foo
INNER JOIN
bar ON foo.bar_id = bar.id
INNER JOIN
baz ON bar.baz_id = baz.id
INNER JOIN
(SELECT
bar_id, MAX(some_int) ct
FROM
foo
WHERE
some_int <= 2
GROUP BY bar_id) max_id ON max_id.bar_id = foo.bar_id
WHERE
foo.some_int = max_id.ct;
不能直接使用 JPQL,但您可以在 Hibernate 之上使用 Blaze-Persistence 来执行此操作。请参阅以下示例:https://persistence.blazebit.com/documentation/1.5/core/manual/en_US/#subquery-in-from-clause
我在这里假设使用 JPA 模型作为示例。您将需要以下 CTE 实体。
@CTE
@Entity
public class MyMaxEntity {
@Id Integer id;
Integer someInt;
}
这是查询
criteriaBuilderFactory.create(entityManager, Foo.class, "foo")
.fetch("bar.baz")
.innerJoinOnSubquery(MyMaxEntity.class, "maxEnt")
.from(Foo.class, "subFoo")
.bind("id").select("subFoo.id")
.bind("value").select("MAX(subFoo.someInt)")
.where("subFoo.someInt").le(2)
.end()
.on("maxEnt.id").eqExpression("foo.bar.id")
.end()
.where("foo.someInt").eqExpression("maxEnt.value")