Lightweight, type-safe JDBC utility for Java 17+
A lightweight Java utility library, keeping you close to SQL while eliminating JDBC boilerplate. Write queries in pure SQL and map results directly to Java objects using modern type-safe method references.
- **Java 17+
- Auto-close
Statement,ResultSet - Simple query/execute API with lambda mapping
- Type-safe mapping via method references, reflection, or tuples
- Fluent API with selectInto, execute, executeBatch
- Built-in support for scalars, tuples, maps, POJOs, records
- Parameter binding via StatementParameters
- Batch execution with
executeBatch
implementation 'de.schaeuffelhut.jdbc:jdbc-util:1.0.0'<dependency>
<groupId>de.schaeuffelhut.jdbc</groupId>
<artifactId>jdbc-util</artifactId>
<version>1.0.0</version>
</dependency>
String name = statementUtil.selectInto(
"SELECT name FROM employees WHERE id = 1",
ResultSetReaders.readOne(),
ResultSetMappers.scalar(ResultTypes.String)
);Object[] tuple = statementUtil.selectInto(
"SELECT id, name FROM employees WHERE id = 1",
ResultSetReaders.readOne(),
ResultSetMappers.tuple(ResultTypes.Integer, ResultTypes.String)
);Map<String, Object> map = statementUtil.selectInto(
"""
SELECT id, name, COUNT(*) AS "count", SUM(id) AS "sum"
FROM employees WHERE id = 1
GROUP BY id, name
""",
ResultSetReaders.readOne(),
ResultSetMappers.map(
ResultTypes.Integer, // id
ResultTypes.String, // name
ResultTypes.Integer, // count
ResultTypes.Integer // sum
)
);record Employee(int id, String name) {}
Employee emp = statementUtil.selectInto(
"SELECT id, name FROM employees WHERE id = 2",
ResultSetReaders.readOne(),
ResultSetMappers.object(Employee::new, ResultTypes.Integer, ResultTypes.String)
);public static class EmployeeDto {
public int id;
public String name;
}
EmployeeDto dto = statementUtil.selectInto(
"SELECT id AS \"id\", name AS \"name\" FROM employees WHERE id = 2",
ResultSetReaders.readOne(),
ResultSetMappers.objectViaReflection(
EmployeeDto.class,
ResultTypes.Integer,
ResultTypes.String
)
);statementUtil.execute(
"""
INSERT INTO employees (id, name) VALUES (?, ?)
ON CONFLICT (id) DO UPDATE SET name = EXCLUDED.name
""",
StatementParameters.Integer(3),
StatementParameters.String("Charlie")
);record Employee(int id, String name){};
List<Employee> employees = List.of(new Employee(1, "Alice"), new Employee(2, "Bob"));
statementUtil.executeBatch(
"INSERT INTO employees (id, name) VALUES (?, ?)",
employees.stream()
.map( e -> new StatementInParameter[]{
StatementParameters.String( e.id ),
StatementParameters.String( e.name )
} )
.toList()
);| Class | Purpose |
|---|---|
ResultSetReaders |
readOne(), readMany(), readScalar() |
ResultSetMappers |
scalar(), tuple(), map(), object(), objectViaReflection() |
ResultTypes |
String, Integer, Long, Boolean, Object(UUID.class), Enum(MyEnum.class) |
StatementParameters |
Object(), String(), Integer(), EnumByName() |
record Realm(UUID uuid, String name) {}
List<Realm> realms = stmt.selectInto(
"""
SELECT r.uuid, r.name
FROM realm r
JOIN realm_member rm ON r.uuid = rm.realm
WHERE rm.user_account = ?
""",
ResultSetReaders.readMany(),
ResultSetMappers.object(
Realm::new,
ResultTypes.Object(UUID.class),
ResultTypes.String
),
StatementParameters.Object(currentUserId)
);MIT – Free for commercial and personal use.
JdbcUtil – SQL First. Java Second. No Boilerplate.
Maintained with love by @fschaeuffelhut