A library for binding results of methods defined in DatabaseMetaData.
All 26 methods in DatabaseMetaData that return ResultSet are bound to type-safe Java classes.
Full documentation lives in the project wiki:
- Home — overview, snapshot, dependencies, basic usage
- API Reference — the bound methods
- Model Notes — binding behavior and catalog/schema/pattern handling
- XML and JSON Binding — marshalling bound records
- Testing and Build — build requirements and running tests
- External Integration Tests — running
ExternalITagainst your own database - Known Issues — driver-specific quirks
See Maven Central for available versions.
<dependency>
<groupId>io.github.jinahya</groupId>
<artifactId>database-metadata-bind</artifactId>
</dependency>try (var connection = dataSource.getConnection()) {
var context = Context.from(connection);
// Get all catalogs
List<Catalog> catalogs = context.getCatalogs();
// Get all tables (null = don't filter)
List<Table> tables = context.getTables(null, null, "%", null);
// Get columns for a specific table
List<Column> columns = context.getColumns("my_catalog", "my_schema", "my_table", "%");
}Each bound method comes in two forms — one that returns a List, and one that hands each row to a
Consumer as it is read:
List<Table> tables = context.getTables(null, null, "%", null); // materializes every row
context.forEachTable(null, null, "%", null, table -> { ... }); // one row at a timeOnce you hold a Table, ask for what belongs to it rather than unpacking its catalog and schema by hand:
List<Column> columns = context.getColumnsOf(table, "%");
List<PrimaryKey> keys = context.getPrimaryKeysOf(table);This is worth preferring: a row's catalog may be null, and passing that straight back through
getColumns(catalog, ...) means do not narrow by catalog rather than this table's catalog, which returns extra
rows instead of an error. See Model Notes and
API Reference.
Both read the same result set and bind the same objects. They differ in when you see each row.
Reach for get* by default — it is the simpler call and the list is yours to keep. Reach for
forEach* when the sweep may be large (getAllColumns() materializes every column in the database;
forEachColumn(...) holds one row at a time), or when you need to read a driver extension that is
not a simple scalar.
That last case has a catch worth knowing before you pick: a driver may return a Blob, Clob,
Array, or SQLXML in getUnknownColumns(), and those are locators that die with the result set —
readable inside a forEach* callback, already dead by the time a get* list reaches you. See
Home for the full comparison and
Model Notes for locator
lifetimes and unknown columns.
See the wiki for more examples, catalog/schema null handling, and per-driver notes.