JDBC
On this page 8 topics
Overview
Topics
- Connections
- PreparedStatement
- ResultSet
- SQL injection prevention (builds on BEG-055)
Learn first
2 h of practice (estimate)
Learning outcomes
- Obtain connections from a
DataSource(connection pool) instead ofDriverManager. - Execute batch inserts and retrieve generated keys.
- Map SQL types to Java types correctly (
numeric↔BigDecimal,timestamptz↔Instant/OffsetDateTime). - Prevent SQL injection in dynamic queries (e.g., user-chosen sort columns via allow-lists).
Lessons
Lab and exercises
Lab
JNR-025-LAB1 · Bulk import
Outcomes: 1–4 · Time: ~2 h
- Create a
producttable (id bigint generated always as identity,name text,price numeric(12,2)). - Import 10,000 products from a provided CSV using a pooled
DataSourceand a batchedPreparedStatement. - Import the same file row by row with auto-commit on; time both with the same data.
- Print the generated keys of the first batch; map
pricetoBigDecimal. - Add a
findAll(sortBy)method whose sort column comes from an allow-list.
Acceptance: measured speed-up shown; no concatenated user input in any SQL.
Exercises (assessment: fix an injectable dynamic query)
| ID | Outcome | Task |
|---|---|---|
| JNR-025-EX01 | 1 | Explain in three sentences why a connection pool beats DriverManager per statement. |
| JNR-025-EX02 | 1 | Rewrite a method that opens DriverManager connections to use an injected DataSource with try-with-resources. |
| JNR-025-EX03 | 2 | Insert five rows with addBatch and print each generated id. |
| JNR-025-EX04 | 3 | Choose the Java type for: numeric(10,2), timestamptz, date, and a nullable bigint. |
| JNR-025-EX05 | 4 | Fix "select * from product where name = '" + name + "'" using a placeholder. |
| JNR-025-EX06 | 4 | Fix "... order by " + request.getParameter("sort") with an allow-list and a default. |
Show solutions
- EX01 Opening a connection costs network round trips, login, and setup; a pool keeps connections open and reuses them, so each statement pays almost nothing and the database is protected from too many connections.
- EX02
try (Connection c = dataSource.getConnection(); PreparedStatement ps = ...) { ... }; theDataSourceis a constructor parameter. - EX03 Prepare with
Statement.RETURN_GENERATED_KEYS,addBatchfive times,executeBatch, loop overgetGeneratedKeys(). - EX04
BigDecimal;InstantorOffsetDateTime;LocalDate;Long(read withgetObject(col, Long.class)). - EX05
prepareStatement("select * from product where name = ?")thenps.setString(1, name). - EX06
String col = SORTABLE.getOrDefault(sort, "name");and concatenate onlycol. - Outcomes 2 and 3 are also checked in the lab (batch timing,
BigDecimalprice).
Quiz
Outcomes: O1 DataSource and pool · O2 batches and generated keys · O3 type mapping · O4 injection prevention.
A self-check for you: nothing is graded, saved or sent anywhere. Choose an answer, then check it. You can try again as often as you like.
Practical part
Six exercises JNR-025-EX01 to EX06 plus the lab; the assessment is fixing an injectable dynamic query (EX05, EX06). Pass: at least five exercises correct, lab speed-up measured, no concatenated user input.
Common mistakes
double for prices; concatenating ORDER BY columns; one connection per statement.
Assessment
Fix an injectable dynamic query.
Career relevance
Understanding what every higher-level abstraction does underneath.