java
43 lines · 7 steps
Streaming large JDBC result sets safely
A JDBC query streams rows one at a time via fetch size and a callback instead of loading everything into memory at once.
Explained by
highlit
1public List<OrderSummary> streamRecentOrders(LocalDateTime since, Consumer<OrderSummary> handler) {
2 String sql = """
3 SELECT id, customer_id, total_cents, status, created_at
4 FROM orders
5 WHERE created_at >= ?
6 ORDER BY created_at
7 """;
8
9 List<OrderSummary> processed = new ArrayList<>();
10
11 try (Connection conn = dataSource.getConnection()) {
12 conn.setAutoCommit(false);
13
14 try (PreparedStatement ps = conn.prepareStatement(
15 sql,
16 ResultSet.TYPE_FORWARD_ONLY,
17 ResultSet.CONCUR_READ_ONLY)) {
18
19 ps.setFetchSize(500);
20 ps.setTimestamp(1, Timestamp.valueOf(since));
21
22 try (ResultSet rs = ps.executeQuery()) {
23 while (rs.next()) {
24 OrderSummary order = new OrderSummary(
25 rs.getLong("id"),
26 rs.getLong("customer_id"),
27 rs.getLong("total_cents"),
28 OrderStatus.valueOf(rs.getString("status")),
29 rs.getTimestamp("created_at").toLocalDateTime());
30
31 handler.accept(order);
32 processed.add(order);
33 }
34 }
35 }
36
37 conn.commit();
38 } catch (SQLException e) {
39 throw new DataAccessException("Failed to stream recent orders", e);
40 }
41
42 return processed;
43}
01 / 01
STEP 01
‹ swipe to step through ›
Walkthrough
Space play
←→ step
click any line
Three takeaways
- 1Setting a fetch size lets the driver pull rows in batches instead of buffering the entire result set in memory.
- 2Nested try-with-resources guarantees every JDBC resource closes in the right order even when errors occur.
- 3A Consumer callback lets callers process each row as it arrives, decoupling iteration from what happens per row.
Related explainers
php
<?php namespace App\Services\Checkout;
Validating coupons with Laravel's Pipeline
pipeline
chain of responsibility
transactions
Intermediate
7 steps
java
@Component @Converter public class EncryptedStringConverter implements AttributeConverter<String, String> {
Transparent column encryption in Spring & JPA
encryption
aes-gcm
jpa-converter
Advanced
10 steps
java
package com.acme.billing.config; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.ConfigurationProperties;
Feature-flagged beans with Spring @ConditionalOnProperty
feature-flags
conditional-beans
strategy-pattern
Intermediate
5 steps
python
import random from typing import Iterator, List
How reservoir sampling picks k items
reservoir-sampling
streaming
randomness
Intermediate
5 steps
java
public static Map<String, String> parseCookieHeader(String header) { Map<String, String> cookies = new LinkedHashMap<>(); if (header == null || header.isBlank()) { return cookies;
Parsing an HTTP Cookie header in Java
string-parsing
http
url-decoding
Intermediate
6 steps
java
public class TimedSocketReader { private static final int READ_TIMEOUT_MS = 5_000; private static final int CONNECT_TIMEOUT_MS = 3_000;
Reading a socket with connect and read timeouts
sockets
timeouts
io
Intermediate
8 steps
Share this explainer
Here's the card — post it anywhere.
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code
Embed this explainer
Drop the interactive walkthrough into a blog or docs. Views never cost a credit.
<iframe src="https://highlit.co/explainers/streaming-large-jdbc-result-sets-safely-explained-java-143a/embed?autoplay=1" width="100%" height="520" loading="lazy" style="border:0"></iframe>
Autoplay is on by default — add ?autoplay=0 to start paused.