带有Spring Boot和QueryDSL的大型结果集

时间:2019-01-20 18:48:38

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

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

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

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

2 个答案:

答案 0 :(得分:0)

此问题的一种解决方法是继续使用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,也将最终对查询所涉及的表进行全面扫描。如果发生这种情况,您将面临性能问题,而不是内存问题。

答案 1 :(得分:0)

使用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();