【问题标题】:Java JDBC Lazy-Loaded ResultSetJava JDBC 延迟加载的结果集
【发布时间】:2010-11-02 07:33:00
【问题描述】:

有没有办法让你通过运行 JDBC 查询获得的 ResultSet 被延迟加载?我希望按照我的要求而不是事先加载每一行。

【问题讨论】:

  • 在不了解您要解决的问题的情况下,我可能会进行全面概括,但如果驱动程序实现确实进行远程调用,这对于潜在的性能问题来说听起来很奇怪对于每一行(正如下面的答案中所指出的,不一定是这种情况)。

标签: java jdbc lazy-loading resultset


【解决方案1】:

here提供了一个答案。

引用:

Presto JDBC 驱动程序从不将整个结果集缓存在内存中。每次请求,服务器 API 最多会向驱动程序返回约 1MB 的数据。驱动程序不会从服务器请求更多数据,直到数据被消耗(通过在 ResultSet 上调用 next() 方法适当的次数)。

由于服务器 API 的工作方式,驱动程序获取大小被忽略(根据 JDBC 规范,这只是一个提示)。

Prove that the setFetchSize is ignored

【讨论】:

    【解决方案2】:

    简答:

    在调用executeQuery()之前使用Statement.setFetchSize(1)

    长答案:

    非常很大程度上取决于您使用的 JDBC 驱动程序。您可能想看看this page,它描述了 MySQL、Oracle、SQL Server 和 DB2 的行为。

    主要收获:

    • 每个数据库(即每个 JDBC 驱动程序)都有自己的默认行为。
    • 有些司机会尊重setFetchSize() 而没有任何警告,而其他司机则需要一些“帮助”。

    MySQL 是一个特别奇怪的例子。见this article。听起来如果你打电话给setFetchSize(Integer.MIN_VALUE),那么它会一次下载一行,但不是很清楚。

    另一个例子:here's the documentation 用于 PostgreSQL 行为。如果开启了自动提交,那么 ResultSet 将一次获取所有的行,但如果它关闭,那么您可以按预期使用setFetchSize()

    要记住的最后一件事:这些 JDBC 驱动程序设置只影响客户端发生的事情。服务器可能仍会将整个结果集加载到内存中,但您可以控制客户端下载结果的方式。

    【讨论】:

    • 这意味着您不能依赖每次调用 ResultSet.next() 检索到的一行,因此,恕我直言,这可能不是您正在尝试的问题的解决方案解决。
    • 嗨尼克。谢谢你的评论。我试图重新解释答案以解释理论上 setFetchSize() 是答案,但同样,这取决于您使用的数据库。这可能是正确的答案,例如,如果 OP 使用 Oracle。
    【解决方案3】:

    您不能通过将 Statement 的 fetch size 设置为 1 来实现这一点吗?

    如果您一次只获取 1 行,则在调用 ResultSet 上的 next() 之前不应加载每一行。

    例如

    Statement statement = connection.createStatement();
    statement.setFetchSize(1);
    ResultSet resultSet = statement.executeQuery("SELECT .....");
    while (resultSet.next())
    {
      // process results. each call to next() should fetch the next row
    }
    

    【讨论】:

    • 您能描述一下如何做到这一点吗?
    • 这仅适用于顺序迭代,并且不允许在初始语句范围之外获取数据。但它在琐碎的情况下使用是一个很好的建议。
    【解决方案4】:

    您会发现使用hibernate 会轻松很多。如果您直接使用 jdbc,则基本上必须自己滚动。

    hibernate 中的获取策略是高度可配置的,并且很可能会提供您甚至没有意识到的性能选项。

    【讨论】:

    • 我认为否决票是因为它没有回答问题,而不是因为建议本身是错误的。
    • Hibernate 通过给你一个 List 来做相反的事情。
    【解决方案5】:

    我认为您想要做的是推迟 ResultSet 本身的实际加载。您需要手动实现。

    【讨论】:

      猜你喜欢
      • 2018-07-08
      • 2016-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-21
      • 2017-05-13
      相关资源
      最近更新 更多