【问题标题】:Large Resultset with Spring Boot and QueryDSL带有 Spring Boot 和 QueryDSL 的大型结果集
【发布时间】:2019-06-14 05:50:03
【问题描述】:

我有一个 Spring Boot 应用程序,我在其中使用 QueryDSL 进行动态查询。 现在应该将结果导出为 csv 文件。 该模型是包含产品的Order。产品应包含在 csv 文件中。 但是,由于有数以百万计的产品的数千个订单,因此不应一次将其加载到内存中。

但是,QueryDSL 不支持 Hibernate (ScrollableResults) 和流提出的解决方案。

如何在仍然使用 QueryDSL 的同时实现这一点(以避免重复过滤逻辑)?

【问题讨论】:

  • 创建一个查询并使用iterate 而不是fetch。这将返回一个惰性迭代器并按需检索数据。在它下面使用ScrollableResults

标签: spring hibernate spring-boot spring-data-jpa querydsl


【解决方案1】:

解决此问题的一种方法是继续使用 offsetlimit 进行迭代。

类似:

long limit = 100;
long lastLimitUsed = 0;

List<MyEntity> entities = new JPAQuery<>(em)
    .from(QMyEntity.entity)
    .limit(limit)
    .offset(lastLimitUsed)
    .fetch();
lastLimitUsed += limit;

通过这种方法,您可以获取更小的数据块。分析limitoffset 字段是否适用于您的查询非常重要。在某些情况下,即使您使用limitoffset,您最终也会对查询中涉及的表进行全面扫描。如果发生这种情况,您将面临性能问题而不是内存问题。

【讨论】:

    【解决方案2】:

    使用 JPAQueryFactory

    // com.querydsl.jpa.impl.JPAQueryFactory
    JPAQueryFactory jpaFctory = new JPAQueryFactory(entityManager);
    
    //
    Expression<MyEntity> select = QMyEntity.myEntity;
    EntityPath<MyEntity> path = QMyEntity.myEntity;
    
    Stream stream = this.jpaQueryFactory
                .select(select)
                .from(entityPath)
                .where(cond)
                .createQuery()   // get jpa query
                .getResultStream();
    
    // do something
    stream.close();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-25
      • 2014-05-11
      • 2020-08-18
      • 1970-01-01
      • 1970-01-01
      • 2021-06-10
      • 2020-01-18
      • 2014-08-12
      相关资源
      最近更新 更多