2010-08-11 68 views
4

我有一个要求,只能从本地访问MySQL数据库。我必须实现一个访问数据库的servlet,以允许此系统中的其他服务器访问数据(servlet将作为代理)。然而,这个系统由下载执行如下语句的大部分数据的远程服务器:从servlet访问数据

select * from database limit 100; 

有人建议我如何写一个servlet,将在一个有效的方式流这样的数据(我是新来的数据库)?

回答

2

首先,我不建议使用这个servlet。查看aioobe和mdma的正确答案。但如果真的没有其他选择,请继续阅读:


的数据只是写入响应作为数据进来,立即不要存放在Java的内存一切。所以基本上:writer.write(resultSet.getString("col"))。此外,在给予ResultSet#next()任何东西之前,MySQL JDBC驱动程序将默认缓存Java内存中的所有内容。您希望通过按照MySQL JDBC driver documentation设置Statement#setFetchSize()来逐行提供数据。

这里有一个开球例如,假设你想输出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) {} 
    } 
} 
1

那么,如果你的目标是完全打开外部主机查询的sql服务器,但由于某种原因不想重新配置它接受外部连接,我建议你简单地建立一个隧道用于服务器侦听的端口。

远程主机将连接到您的应用程序(在本地主机上运行),该应用程序反过来简单地连接到sql服务器并来回传输数据流。

+1

这是最简单的解决方案;使用数据库的本地通信方法可能比通过servlet/http响应运行所有内容的时间要快 – 2010-08-11 13:39:10