【问题标题】:Is it possible to transform a query joining onto a subselect into JPQL?是否可以将连接到子选择的查询转换为 JPQL?
【发布时间】:2020-05-31 17:36:39
【问题描述】:

鉴于以下包含子选择连接的本机 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;

【问题讨论】:

    标签: sql hibernate spring-data-jpa jpql


    【解决方案1】:

    不直接使用 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")
    

    【讨论】:

    • 这看起来很有希望,但我看不出如何为我的示例(或任何接近的东西)正确实现它。文档中的子查询示例有点做作。
    猜你喜欢
    • 1970-01-01
    • 2020-08-10
    • 2021-02-15
    • 2019-09-19
    • 2013-05-29
    • 1970-01-01
    • 1970-01-01
    • 2021-08-08
    • 1970-01-01
    相关资源
    最近更新 更多