Utilities for working with the raw JDBC api.
Includes
- Utilities for reading data from
ResultSet
s - An
UncheckedSQLException
for when throwing aSQLException
is inconvenient, but might need to be recovered later. - A
SettableParameter
interface, for when String Templates are re-previewed.
<dependency>
<groupId>dev.mccue</groupId>
<artifactId>jdbc</artifactId>
<version>2024.12.20</version>
</dependency>
dependencies {
implementation("dev.mccue:jdbc:2024.12.20")
}
These examples use sqlite.
ResultSets
includes helpers for reading potentially null
primitive types from a ResultSet
import dev.mccue.jdbc.ResultSets;
void main() throws Exception {
var db = new SQLiteDataSource();
db.setUrl("jdbc:sqlite:test.db");
try (var conn = db.getConnection()) {
try (var stmt = conn.prepareStatement("""
SELECT number
FROM widget
LIMIT 1
""")) {
var rs = stmt.executeQuery();
// Methods exist for all primitives except char
// (which doesn't have a method on ResultSet)
var number = ResultSets.getIntegerNullable(rs, "number");
}
}
}
If you want to read a column that is primitive, but you assume
is not null, there are helpers which will throw a SQLException
early if that assumption is violated.
import dev.mccue.jdbc.ResultSets;
void main() throws Exception {
var db = new SQLiteDataSource();
db.setUrl("jdbc:sqlite:test.db");
try (var conn = db.getConnection()) {
try (var stmt = conn.prepareStatement("""
SELECT number
FROM widget
LIMIT 1
""")) {
var rs = stmt.executeQuery();
// Methods exist for all primitives except char
// (which doesn't have a method on ResultSet)
var number = ResultSets.getIntegerNotNull(rs, "number");
}
}
}
Often when going through a ResultSet
you will want to materialize a whole row.
import dev.mccue.jdbc.ResultSets;
public record Widget(int number) {}
void main() throws Exception {
var db = new SQLiteDataSource();
db.setUrl("jdbc:sqlite:test.db");
try (var conn = db.getConnection()) {
try (var stmt = conn.prepareStatement("""
SELECT number
FROM widget
LIMIT 1
""")) {
var rs = stmt.executeQuery();
var widget = ResultSets.getRecord(rs, Widget.class);
System.out.println(widget);
}
}
}
If the name of a record component doesn't line up with what you want pulled from a
ResultSet
, you can use the @Column
annotation.
import dev.mccue.jdbc.Column;
import dev.mccue.jdbc.ResultSets;
public record Widget(@Column(label = "number") int n) {
}
void main() throws Exception {
var db = new SQLiteDataSource();
db.setUrl("jdbc:sqlite:test.db");
try (var conn = db.getConnection()) {
try (var stmt = conn.prepareStatement("""
SELECT number
FROM widget
LIMIT 1
""")) {
var rs = stmt.executeQuery();
var widget = ResultSets.getRecord(rs, Widget.class);
System.out.println(widget);
}
}
}