2010-08-11 65 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