| Lesson 6 | PreparedStatement and Result Set Metadata — Conclusion |
| Objective | Summarize modern JDBC practices for batched updates with PreparedStatement and show how to use ResultSet metadata safely and efficiently. |
Editorial note: The prior version mixed older PDF excerpts with references to custom XML utilities and general database design notes. It also emphasized Statement and string-built SQL. This rewrite streamlines to a clear outcome: use PreparedStatement for parameterized DML (and batching) and leverage ResultSetMetaData only when you truly need dynamic schema details. Any XML helper classes are omitted; standard JDBC/Java APIs and try-with-resources cover common needs.
Modern JDBC (4.2+) favors PreparedStatement with explicit transactions for updates, and uses ResultSetMetaData to inspect result shapes when your code must adapt dynamically. Together, these features let you write secure, efficient data-access code that scales from fixed schemas to ad-hoc queries.
?) — safer and cache-friendly.setAutoCommit(false) → work → commit() (or rollback() on error).addBatch() + executeBatch() (or executeLargeBatch()).
import javax.sql.DataSource;
import java.sql.*;
DataSource ds = MyDataSourceProvider.getDataSource(); // e.g., HikariCP pool
String sql = "UPDATE hospitals SET phoneno = ? WHERE id = ?";
try (Connection con = ds.getConnection()) {
con.setAutoCommit(false);
try (PreparedStatement ps = con.prepareStatement(sql)) {
ps.setString(1, "(019) 788-7130");
ps.setInt(2, 10101);
ps.addBatch();
ps.setString(1, "(019) 788-7034");
ps.setInt(2, 10102);
ps.addBatch();
int[] counts = ps.executeBatch();
con.commit();
System.out.println("Rows affected: " + java.util.Arrays.toString(counts));
} catch (BatchUpdateException bue) {
con.rollback();
System.err.println("Partial results: " + java.util.Arrays.toString(bue.getUpdateCounts()));
throw bue;
} catch (SQLException ex) {
con.rollback();
throw ex;
}
}
Do not mix DDL (e.g., ALTER TABLE) into DML batches; behavior is driver-specific and not portable.
ResultSetMetaData describes the columns returned by a query—count, names, types, and properties. Most CRUD code already knows the schema and doesn’t need it. Use metadata when your code must render, transform, or validate results generically (e.g., admin consoles, report builders, CSV/JSON exporters).
import javax.sql.DataSource;
import java.sql.*;
DataSource ds = MyDataSourceProvider.getDataSource();
String sql = "SELECT id, name, created_at FROM hospitals ORDER BY id";
try (Connection con = ds.getConnection();
PreparedStatement ps = con.prepareStatement(sql);
ResultSet rs = ps.executeQuery()) {
ResultSetMetaData md = rs.getMetaData();
int cols = md.getColumnCount();
System.out.println("Columns: " + cols);
for (int i = 1; i <= cols; i++) {
System.out.printf("#%d name=%s type=%s precision=%d nullable=%s%n",
i,
md.getColumnLabel(i),
md.getColumnTypeName(i),
md.getPrecision(i),
(md.isNullable(i) == ResultSetMetaData.columnNullable ? "YES" : "NO"));
}
// Consume rows normally...
while (rs.next()) {
// ...
}
}
Related metadata you may encounter:
DriverManager for pooling and configuration.clearBatch() between chunks.BatchUpdateException.getUpdateCounts() to analyze partial success.DatabaseMetaData.supportsBatchUpdates().PreparedStatement is preferred over Statement for updates and batching.ResultSetMetaData to dynamically inspect column names, types, and attributes.Next Module: Stored procedures and transactions — calling procedures, passing parameters, and managing ACID boundaries with care.