在Java EE应用程序中处理大记录
问题内容:
有一个phonenumbers
包含两列的表:id
和number
。half a million entries
桌子上有关于。数据库是MySQL
。
要求是开发一个连接到该数据库的简单Java EE应用程序,该应用程序允许用户通过遵循特定的URL 下载所有number
值comma separated style
。
如果我们将所有值组合成一个大块String array
,然后将它们连接在一起(所有值之间用逗号分隔)String
,然后将其发送给用户,这听起来是一个合适的解决方案吗?
该应用程序不是公开的,将由有限号使用。人。
问题答案:
最好的选择是 不要 以任何方式将数据存储在Java内存中,而只是在数据进入时 立即 将获取的数据写入响应中。您还需要配置MySQL
JDBC驱动程序以逐行提供结果集通过Statement#setFetchSize()
为每MySQL
JDBC驱动程序文件
,否则将缓存整个事情的记忆。
假设您熟悉Servlet,这是一个启动示例,其中考虑了所有方面:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/plain");
response.setHeader("Content-Disposition", "attachment;filename=numbers.txt"); // Force download popup.
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
Writer writer = response.getWriter();
try {
connection = database.getConnection();
statement = connection.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
statement.setFetchSize(Integer.MIN_VALUE);
resultSet = statement.executeQuery("SELECT number FROM phonenumbers");
while (resultSet.next()) {
writer.write(resultSet.getString("number"));
if (!resultSet.isLast()) {
writer.write(",");
}
}
} catch (SQLException e) {
throw new ServletException("Query failed!", e);
} finally {
if (resultSet != null) try { resultSet.close; } catch (SQLException logOrIgnore) {}
if (statement != null) try { statement.close; } catch (SQLException logOrIgnore) {}
if (connection != null) try { connection.close; } catch (SQLException logOrIgnore) {}
}
}