0

我在 Spring 中有一个 Web 应用程序,它具有从来自大型 Oracle 数据库的结果集中生成 CSV/Excel 电子表格的功能要求。预期的行数在 300,000 - 1,000,000 范围内。处理时间并不像保持应用程序稳定那么大——现在,非常大的结果集会导致它耗尽内存并崩溃。

在这样的正常情况下,我会使用分页并让 UI 一次显示有限数量的结果。但是,在这种情况下,我需要能够在一个文件中生成整个集合,无论它有多大,以供离线使用。

我已将问题隔离到用于将结果集转换为对象的 ParameterizedRowMapper 上,这就是我遇到的问题。

我可以使用哪些技术来控制此操作?分页仍然是一种选择吗?

4

4 回答 4

1

一个简单的答案:

使用 JDBC 记录集(或类似的,具有适当的数组/获取大小)并将数据写回 LOB,可以是临时的,也可以写回数据库中。

另一种选择:

使用数据库中的 PL/SQL 为您的记录集以 CSV 格式写入使用 UTL_FILE 的文件。由于文件将在数据库服务器上,而不是在客户端上,因此使用 UTL_SMTP 或 JavaMail 使用 Java 存储过程来邮寄文件。毕竟,如果有人看到沙漏反复翻转等待生成 100 万行记录集,我会感到惊讶。

于 2010-08-25T17:20:23.357 回答
1

您可以单独处理每一行并使用输出流将输出直接发送到 Web 浏览器,而不是将整个文件加载到内存中。例如,在 servlets API 中,您可以从 ServletResponse.getOutputStream() 获取输出流,然后简单地将结果 CSV 行写入该流。

于 2010-08-25T17:59:54.057 回答
0

我会反对这些要求——它们听起来很不自然。如果您的应用程序失败,或者在用户查看该数据之前断电,会发生什么?

从您上面的评论中,听起来您知道答案——您需要文件系统或 Oracle 访问权限才能完成您的工作。

您被要求生成一些数据 - sql 无法重复的数据?如果它是可重复的,您只需将数据页一次发送回用户。

由于我猜这个报告与您的数据的当前状态有关,如果您无法将其流式传输给用户,您需要将该结果存储在某个地方。我会在 oracle 中编写一个存储过程——不通过网络来回发送数据要快得多。如果你有特殊的工具或者它更简单,听起来在java端做这件事没有什么问题。

您可以安排此报告每周运行一次吗?

于 2010-08-25T18:37:13.920 回答
0

您是否考虑过具有 1,000,000 行的 Excel 电子表格的性能?

于 2010-08-25T19:02:18.580 回答