Java JDBC 延迟加载的结果集

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/984073/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 14:41:24  来源:igfitidea点击:

Java JDBC Lazy-Loaded ResultSet

javajdbclazy-loadingresultset

提问by Nathaniel Flath

Is there a way to get a ResultSet you obtain from running a JDBC query to be lazily-loaded? I want each row to be loaded as I request it and not beforehand.

有没有办法让你从运行 JDBC 查询获得的 ResultSet 延迟加载?我希望每一行在我请求时加载,而不是事先加载。

回答by Matt Solnit

Short answer:

简答:

Use Statement.setFetchSize(1)before calling executeQuery().

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

Long answer:

长答案:

This depends verymuch on which JDBC driver you are using. You might want to take a look at this page, which describes the behavior of MySQL, Oracle, SQL Server, and DB2.

这取决于非常多的哪个JDBC驱动程序所使用。您可能想看看这个页面,它描述了 MySQL、Oracle、SQL Server 和 DB2 的行为。

Major take-aways:

主要收获:

  • Each database (i.e. each JDBC driver) has its own default behavior.
  • Some drivers will respect setFetchSize()without any caveats, whereas others require some "help".
  • 每个数据库(即每个 JDBC 驱动程序)都有自己的默认行为。
  • 有些司机会尊重setFetchSize()而没有任何警告,而另一些司机则需要一些“帮助”。

MySQL is an especially strange case. See this article. It sounds like if you call setFetchSize(Integer.MIN_VALUE), then it will download the rows one at a time, but it's not perfectly clear.

MySQL 是一个特别奇怪的案例。请参阅这篇文章。听起来如果你调用setFetchSize(Integer.MIN_VALUE),那么它会一次下载一行,但它并不完全清楚。

Another example: here's the documentationfor the PostgreSQL behavior. If auto-commit is turned on, then the ResultSet will fetch all the rows at once, but if it's off, then you can use setFetchSize()as expected.

另一个例子:这里是PostgreSQL 行为的文档。如果自动提交打开,那么 ResultSet 将一次获取所有行,但如果它关闭,那么您可以setFetchSize()按预期使用。

One last thing to keep in mind: these JDBC driver settings only affect what happens on the client side. The server may still load the entire result set into memory, but you can control how the client downloadsthe results.

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

回答by Mark

Could you not achieve this by setting the fetch size for your Statement to 1?

您不能通过将 Statement 的提取大小设置为 1 来实现这一点吗?

If you only fetch 1 row at a time each row shouldn't be loaded until you called next() on the ResultSet.

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

e.g.

例如

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
}

回答by AgileJon

I think what you would want to do is defer the actually loading of the ResultSet itself. You would need to implement that manually.

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

回答by dmigo

There is an answer provided here.

这里提供一个答案。

Quote:

引用:

The Presto JDBC driver never buffers the entire result set in memory. The server API will return at most ~1MB of data to the driver per request. The driver will not request more data from the server until that data is consumed (by calling the next()method on ResultSet an appropriate number of times).

Because of how the server API works, the driver fetch size is ignored (per the JDBC specification, it is only a hint).

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

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

Prove that the setFetchSizeis ignored

证明setFetchSize被忽略

回答by Matt

You will find this a LOT easier using hibernate. You will basically have to roll-your-own if you are using jdbc directly.

你会发现使用hibernate会容易很多。如果您直接使用 jdbc,您基本上必须自己动手。

The fetching strategies in hibernate are highly configurable, and will most likely offer performance options you weren't even aware of.

Hibernate 中的获取策略是高度可配置的,并且很可能会提供您甚至不知道的性能选项。