我有一个需求,即只能从本地主机访问mysql数据库。我必须实现一个servlet,允许该系统中的其他服务器访问数据(servlet将作为代理工作)。然而,这个系统包括一个远程服务器,它通过执行像下面这样的语句来下载大量数据:
select * from database limit 100;
有人可以建议我如何编写一个servlet以高效地流式传输此类数据吗(我对数据库还很陌生)?
writer.write(resultSet.getString("col"))
。此外,MySQL JDBC驱动程序默认会将所有内容缓存在Java的内存中,然后再将其提供给ResultSet#next()
。您可以根据MySQL JDBC驱动程序文档设置Statement#setFetchSize()
,以便让它逐行立即提供数据。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) {}
}
}
如果您的目标是完全打开 SQL Server,以便外部主机可以查询,但由于某种原因不想重新配置它以接受外部连接,我建议您仅为服务器侦听的端口设置隧道。
远程主机将连接到您在本地主机上运行的应用程序,该应用程序将简单地连接到 SQL Server 并传递数据流来回。