Статьи

Java: потоковая передача JDBC ResultSet как CSV

В моем предыдущем посте я показал, как преобразовать java.sql.ResultSet в JSON и java.sql.ResultSet его обратно вызывающей стороне. Этот пост о потоковой передаче в формате CSV. Потоковая передача позволяет вам постепенно передавать данные, не загружая их все в память сервера.

Например, рассмотрим следующий ResultSet :

1
2
3
4
5
6
7
+---------+-----+
| Name    | Age |
+---------+-----+
| Alice   |  20 |
| Bob     |  35 |
| Charles |  50 |
+---------+-----+

Соответствующий CSV:

1
2
3
4
name,age
Alice,20
Bob,35
Charles,50

Следующий класс (также доступный в моем репозитории GitHub ) может быть использован для преобразования ResultSet в CSV. Обратите внимание, что этот класс реализует ResultSetExtractor Spring, который может использоваться JdbcTemplate для извлечения результатов из ResultSet .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/**
 * Streams a ResultSet as CSV.
 */
public class StreamingCsvResultSetExtractor
                         implements ResultSetExtractor<Void> {
 
  private static char DELIMITER = ',';
 
  private final OutputStream os;
 
  /**
   * @param os the OutputStream to stream the CSV to
   */
  public StreamingCsvResultSetExtractor(final OutputStream os) {
    this.os = os;
  }
 
  @Override
  public Void extractData(final ResultSet rs) {
    try (var pw = new PrintWriter(os, true)) {
      final var rsmd = rs.getMetaData();
      final var columnCount = rsmd.getColumnCount();
      writeHeader(rsmd, columnCount, pw);
      while (rs.next()) {
        for (var i = 1; i <= columnCount; i++) {
          final var value = rs.getObject(i);
          pw.write(value == null ? "" : value.toString());
          if (i != columnCount) {
            pw.append(DELIMITER);
          }
        }
        pw.println();
      }
      pw.flush();
    } catch (final SQLException e) {
      throw new RuntimeException(e);
    }
    return null;
  }
 
  private static void writeHeader(final ResultSetMetaData rsmd,
      final int columnCount, final PrintWriter pw) throws SQLException {
    for (var i = 1; i <= columnCount; i++) {
      pw.write(rsmd.getColumnName(i));
      if (i != columnCount) {
        pw.append(DELIMITER);
      }
    }
    pw.println();
  }
}

Чтобы использовать это в веб-сервисе с JAX-RS:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
import javax.ws.rs.core.StreamingOutput;
 
@GET
@Path("runQuery")
@Produces("text/csv")
public StreamingOutput runQuery() {
  return new StreamingOutput() {
    @Override
    public void write(final OutputStream os)
        throws IOException, WebApplicationException {
      jdbcTemplate.query("select name, age from person",
                   new StreamingCsvResultSetExtractor(os));
    }
  };
}

Похожие сообщения:

Потоковый набор результатов JDBC как JSON

Опубликовано на Java Code Geeks с разрешения Фахда Шарифа, партнера нашей программы JCG . См. Оригинальную статью здесь: Java: потоковая передача JDBC ResultSet как CSV

Мнения, высказанные участниками Java Code Geeks, являются их собственными.