Trước hết, tôi không khuyên bạn nên sử dụng một servlet cho việc này. Xem câu trả lời của aioobe và mdma để có cách tiếp cận phù hợp. Nhưng nếu thực sự không có lựa chọn nào khác, thì hãy tiếp tục đọc:
Chỉ cần ghi dữ liệu vào phản hồi ngay lập tức khi dữ liệu đến. Không lưu trữ mọi thứ trong bộ nhớ của Java. Về cơ bản:writer.write(resultSet.getString("col"))
. Hơn nữa, trình điều khiển MySQL JDBC theo mặc định sẽ lưu trữ mọi thứ trong bộ nhớ của Java trước khi đưa bất kỳ thứ gì vào ResultSet#next()
. Bạn muốn nó cung cấp dữ liệu ngay lập tức theo từng hàng bằng cách đặt Statement#setFetchSize()
theo tài liệu trình điều khiển MySQL JDBC
.
Đây là một ví dụ khởi động, giả sử bạn muốn xuất dữ liệu ở định dạng CSV:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/csv");
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
PrintWriter 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 col1, col2, col3 FROM tbl");
while (resultSet.next()) {
writer.append(resultSet.getString("col1")).append(',');
writer.append(resultSet.getString("col2")).append(',');
writer.append(resultSet.getString("col3")).println();
// PS: don't forget to sanitize quotes/commas as per RFC4130.
}
} 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) {}
}
}