我有一个Spring Boot应用程序,我在其中使用QueryDSL进行动态查询。现在,结果应导出为csv文件。该模型是包含产品的Order
。产品应包含在 csv 文件中。但是,由于有数千个订单和数百万种产品,因此不应一次将其加载到内存中。
然而,由Hibernate(ScrollableResults
)和流提出的解决方案不受QueryDSL的支持。
如何在仍然使用QueryDSL的情况下实现这一点(以避免过滤逻辑的重复)?
的一种解决方法是使用 offset
和 limit
继续迭代。
像这样:
long limit = 100;
long lastLimitUsed = 0;
List<MyEntity> entities = new JPAQuery<>(em)
.from(QMyEntity.entity)
.limit(limit)
.offset(lastLimitUsed)
.fetch();
lastLimitUsed += limit;
使用这种方法,您可以获取较小的数据块。分析"limit
"和"offset
"字段是否适用于您的查询非常重要。在某些情况下,即使您使用 limit
和 offset
,您最终也会对查询中涉及的表进行完全扫描。如果发生这种情况,您将面临性能问题而不是内存问题。
使用 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();