3

、およびphonenumbersの 2 つの列を持つテーブルがあります。表には約あります。データベースはです。idnumberhalf a million entriesMySQL

要件は、そのデータベースに接続された単純な Java EE アプリケーションを開発することです。これにより、ユーザーは特定の URL をたどってすべてのnumber値をダウンロードできます。comma separated style

すべての値を巨大な形式で取得し、String array(すべての値の間にコンマを入れて) 形式で連結し、Stringそれをユーザーに送信すると、適切な解決策に聞こえますか?

アプリケーションは公開されておらず、限られた番号で使用されます。人の。

4

3 に答える 3

9

最善の策は、Java のメモリにデータを保存するのではなく、データが入ってきたらすぐに取得したデータを応答に書き込むことです。結果セットを行ごとに提供するように MySQL JDBC ドライバーを構成する必要もあります。MySQL JDBC ドライバーのドキュメントに従ってStatement#setFetchSize()、それ以外の場合はすべてをメモリにキャッシュします。

サーブレットに精通していると仮定して、すべてを考慮したキックオフの例を次に示します。

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    response.setContentType("text/plain");
    response.setHeader("Content-Disposition", "attachment;filename=numbers.txt"); // Force download popup.

    Connection connection = null;
    Statement statement = null;
    ResultSet resultSet = null;
    Writer 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 number FROM phonenumbers");

        while (resultSet.next()) {
            writer.write(resultSet.getString("number"));
            if (!resultSet.isLast()) {
                writer.write(",");
            }
        }
    } 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) {}
    }
}
于 2010-02-02T00:45:34.613 に答える
1

CSV 出力を適切にフォーマットするには、もう少し作業が必要です。このような既存のライブラリを使用して出力ファイルを生成するのが最も簡単です。

ディスク上のファイル (Web サーバー上) に出力を生成し、ブラウザーをそのファイルにリダイレクトする (cron ジョブなどを使用して古いデータをクリーンアップする) か、結果を直接ユーザーにストリーミングすることができます。

直接ストリーミングしている場合は、MIME タイプをユーザーのブラウザでダウンロードをトリガーするもの (例: text/csv または text/comma-separated-values) に設定してください。

于 2010-02-01T23:35:51.590 に答える
0

Mysql 5.1以降を使用している場合は、独自の構文を使用してファイルをどこかにダンプし、サーブレット応答でストリーミングします。

SELECT a,b,a+b INTO OUTFILE '/tmp/result.txt'
  FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
  LINES TERMINATED BY '\n'
  FROM test_table;

http://dev.mysql.com/doc/refman/5.1/en/select.html

非常に多くのレコードについて、JDBCを引き続き使用する場合は、次のことを試してください。

  • レコード数をフェッチします(クエリ制限を使用して)いくつかのレコードをフェッチし、それらを書き込みます
  • チャンク内のレコード数に達した場合、レコードの最大数に達するまで別のレコードをフェッチします
于 2010-02-02T00:48:00.023 に答える