Tout d'abord, je ne recommande pas d'utiliser un servlet pour cela. Voir les réponses de aioobe et mdma pour la bonne approche. Mais s'il n'y a vraiment pas d'autre option, continuez à lire :
Écrivez simplement les données dans la réponse immédiatement au fur et à mesure que les données arrivent. Ne stockez pas tout dans la mémoire de Java. Donc en gros :writer.write(resultSet.getString("col"))
. De plus, le pilote MySQL JDBC mettra par défaut tout en cache dans la mémoire de Java avant de donner quoi que ce soit à ResultSet#next()
. Vous aimeriez le laisser donner les données immédiatement ligne par ligne en définissant le Statement#setFetchSize()
conformément à la documentation du pilote MySQL JDBC
.
Voici un exemple de lancement, en supposant que vous souhaitiez générer les données au format 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) {}
}
}