来自 PostgreSQL 的流行(带提取大小)

Hol*_*ncy 7 java postgresql jpa spring-boot spring-boot-jpa

我想从 PostgreSQL 11.2 流式传输结果,而不是一次将所有结果读取到内存中。我使用最新的稳定版 SpringBoot 2.1.4.RELEASE。

我阅读了如何在 MySQL 中执行此操作的文章。 http://knes1.github.io/blog/2015/2015-10-19-streaming-mysql-results-using-java8-streams-and-spring-data.html 我还阅读了如何在 PostgreSQL 中执行此操作的文章: Postgresql 中的 Java 8 JPA 存储库流逐行

我有这样的存储库:

public interface ProductRepository extends JpaRepository<Product, UUID> {
    @Query("SELECT p from Product p")
    @QueryHints(value = @QueryHint(name = HINT_FETCH_SIZE, value = "50"))
    Stream<Product> streamAll();
}
Run Code Online (Sandbox Code Playgroud)

比我这样使用流:

  productRepository.streamAll().forEach(product -> export(product));
Run Code Online (Sandbox Code Playgroud)

为了使示例更简单,'export' 方法完全为空。

当我调用该方法时,我看到 Hibernate 查询

Hibernate: select product0_.id as id1_0_, product0_.created as created2_0_, product0_.description as descript3_0_, product0_.name as name4_0_, product0_.product_type_id as product_5_0_ from products product0_ order by product0_.id
Run Code Online (Sandbox Code Playgroud)

一段时间后,我出现了 OutOfMemoryError。查询提示没有帮助。

如何使用 Spring Boot 存储库(甚至 EntityManager)读取数据并以最佳方式从 DB 加载行。我知道我可以进行分页,但正如所写的文章一样,这不是最佳方式。

Dav*_*INO 2

目前使用 spring 检索所有数据,并且 Stream 仅应用于内存中已有的数据。

如果您查看其来源,org.springframework.data.jpa.provider.PersistenceProvider它似乎使用 aScrollableResults来传输数据。

通常ScrollableResults检索内存中的所有数据。

您可以在此处找到使用 MySql 数据库的有趣完整分析,但对于 Postgres 数据库可能也有同样的效果。

因此,如果您认为使用实际上不需要使用大量内存的解决方案,那么它也会这样做,因为底层实现没有使用最佳实现。