【问题标题】:Spring data specification inner join subquerySpring数据规范内连接子查询
【发布时间】:2020-06-10 10:36:18
【问题描述】:

我有一个用 Spring Boot 版本 1.5.x 编写的项目,它连接到 MariaDB 数据库和几个表,它们之间存在大量关系。为了查询数据库,我使用了 org.springframework.data.jpa.repository 中提供的 JpaSpecificationExecutor 接口。我们使用规范的原因是构建动态查询,而不必为存储库本身中的每个过滤器可能性编写新查询。在实体本身中,每个关系都有 Lazy fetchtype。此外,关系的获取是动态的,并且每次都不相同,我还在规范中定义了必须获取的内容。

因为我们有一个大数据集,所以我们实现了分页,同样使用了 JpaSpecificationExecutor 接口提供的方法。现在我注意到,每次我要求获取要获取的 OneToMany 关系时,分页在内存中而不是在数据库中执行,限制从查询中删除。这种行为是可以预料的,但现在我正在寻找一种解决方法。请考虑以下示例:

例如,我们有 3 个表:Person、Role 和 Title。每个人都可以有多个角色和多个头衔。我们考虑解决问题的一种方法是使用以下查询:

SELECT 
    *
FROM
    Person p
        JOIN
    Role r on r.f_person = p.id
        JOIN
    Title t on t.f_person = p.id
        JOIN
    (SELECT 
        p2.id
    FROM
        Person p2
    WHERE
        p2.name LIKE '%John%'
    ORDER BY p2.name DESC
    LIMIT 100 OFFSET 100) AS p2 ON p2.id = p.id

有没有办法在规范中或使用实体管理器来构建此查询,以便我们可以保持查询的动态特性。

【问题讨论】:

    标签: hibernate jpa spring-data-jpa spring-data criteria-api


    【解决方案1】:

    我找到了这张关于 Hibernate 的票: https://hibernate.atlassian.net/browse/HHH-3356

    这告诉我,我正在寻找的功能暂时不适用于 Hibernate。我将我们的查询分成两部分,一个获取分页和排序的所有实体的 ID,然后根据这些 ID 获取所有实体。可能不是最高效的解决方案,但它可以工作,而且比完全没有分页要快得多。

    【讨论】:

      【解决方案2】:

      我建议为此尝试 Blaze-Persistence,因为它会生成高效的分页查询。 Blaze-Persistence 是一个建立在 JPA 之上的查询构建器 API,支持高级 DBMS 功能。分页方面,它非常强大,还支持键集分页,还有其他一些技巧。

      感谢spring数据集成,只需要配置:https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features

      除此之外,我只能建议您考虑在此基础上使用 Blaze-Persistence Entity-Views 以进一步提高性能。如果您愿意,您甚至可以进行动态提取:https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#fetching-a-data-subset

      根据我的阅读,您可能会从GraphQL integration 中受益最多。

      【讨论】:

        猜你喜欢
        • 2014-05-18
        • 1970-01-01
        • 1970-01-01
        • 2015-06-03
        • 1970-01-01
        • 2011-10-07
        • 2012-08-17
        • 2012-12-25
        相关资源
        最近更新 更多