Java JDBC Lazy-Loaded ResultSet

时间:2009-06-11 22:20:52

标签: java jdbc lazy-loading resultset

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

5 个答案:

答案 0 :(得分:36)

简答:

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

答案很长:

这取决于非常您使用的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驱动程序设置仅影响客户端发生的事情。服务器仍然可以将整个结果集加载到内存中,但您可以控制客户端下载结果的方式。

答案 1 :(得分:3)

您是否可以通过将Statement的抓取大小设置为1来实现此目的?

如果您一次只获取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
}

答案 2 :(得分:0)

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

答案 3 :(得分:0)

提供了答案here

引用:

  

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

     

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

Prove that the setFetchSize is ignored

答案 4 :(得分:-3)

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

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