代码之家  ›  专栏  ›  技术社区  ›  bart

从servlet访问数据

  •  4
  • bart  · 技术社区  · 14 年前

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

    select * from database limit 100;
    

    有人能建议我如何编写一个servlet,以一种有效的方式流式处理这些数据吗(我对数据库是新手)?

    3 回复  |  直到 14 年前
        1
  •  2
  •   BalusC    14 年前

    首先,我不建议为此使用servlet。正确的方法见Aoobe和MDMA的答案。但如果真的没有其他选择,那么继续阅读:


    只需将数据写入响应 立即 当数据进入时。不要把所有东西都存储在Java的内存中。所以基本上: writer.write(resultSet.getString("col")) . 此外,MySQL JDBC驱动程序将默认地缓存Java内存中的所有内容,然后再提供任何东西。 ResultSet#next() . 您希望通过设置 Statement#setFetchSize() 按照 MySQL JDBC driver documentation .

    下面是一个启动示例,假设您希望以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) {}
        }
    }
    
        2
  •  1
  •   aioobe    14 年前

    好吧,如果您的目标是完全打开SQL Server以供外部主机查询,但出于某种原因不想将其重新配置为接受外部连接,那么我建议您只为服务器侦听的端口设置一个通道。

    远程主机将连接到您的应用程序(在本地主机上运行),而本地主机则直接连接到SQL服务器并来回传递数据流。

        3
  •  1
  •   mdma    14 年前

    一个JDBC代理会给您开箱即用的东西,例如 Virtual JDBC .