java / intermediate
Snippet
Streaming Massive Database ResultSets with Spring JdbcTemplate RowCallbackHandler
Loading millions of database rows into memory as domain objects can easily cause OutOfMemoryErrors. Using RowCallbackHandler combined with an explicit fetch size processes rows sequentially without buffering whole datasets in memory.
snippet.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Servicepublic class ReportExportService {private final JdbcTemplate jdbcTemplate;public ReportExportService(JdbcTemplate jdbcTemplate) {this.jdbcTemplate = jdbcTemplate;}public void streamLargeDataset(OutputStream outputStream) {jdbcTemplate.setFetchSize(500);jdbcTemplate.query("SELECT id, payload FROM large_events", (RowCallbackHandler) rs -> {String record = rs.getLong("id") + "," + rs.getString("payload") + "\n";outputStream.write(record.getBytes(StandardCharsets.UTF_8));});}}
spring
Breakdown
1
jdbcTemplate.setFetchSize(500);
Instructs the JDBC driver to retrieve rows in batches of 500 rather than fetching all records at once.
2
jdbcTemplate.query("SELECT id, payload FROM large_events", (RowCallbackHandler) rs -> {
Executes the query and invokes the streaming callback per individual row without building an in-memory list.
3
outputStream.write(record.getBytes(StandardCharsets.UTF_8));
Flushes each transformed record directly to the destination stream to keep memory allocation minimal.