Jdbi: SQL access for Java that stays out of the JDBC ceremony
The Jdbi library provides convenient, idiomatic access to relational databases in Java and other JVM technologies such as Kotlin, Clojure or Scala.
At a glance
- What is it?
- A mature library that sits on top of JDBC and gives Java, Kotlin and other JVM languages a small API for binding arguments, mapping rows and keeping SQL where your team can read it.
- Who is it for?
- Jdbi's bet is that the right amount of abstraction over JDBC is small: parameters bound by name or bean, results mapped into your own types, and no ORM hiding the SQL. That bet is why the module list is long while the core stays small, and why plugins like jackson2, jackson3, guava and vavr can add mapping without changing how a query is written.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 8 days ago.
- What is it written in?
- Mainly Java, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 28, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A small layer over JDBC rather than a replacement for it
The README states the premise in one sentence: Jdbi is built on top of JDBC, and if your database has a JDBC driver, you can use Jdbi with it. Nothing here replaces the driver or the connection pool. That decision shapes everything else in the project, including how small the core is and how the rest of the library is organised.
What Jdbi adds is convenience and idiom, as the repository description puts it, for Java and for other JVM languages including Kotlin, Clojure and Scala. The unit of work is a `Handle`, which holds a connection, and the row mapping is done into your own classes rather than into an object graph managed by the library. You keep writing SQL; you stop hand-assembling prepared statement parameters.
The project describes its own footprint as very small for the core while supporting a long list of projects for mapping data and supporting data types. The topic list backs that up with `jdbc`, `java`, `kotlin` and `sql`, and the license is Apache-2.0. The homepage is jdbi.org, which is where the developer guide and Javadoc live rather than in this repository.
One directory per integration, and what they tell you
The repository tree is the clearest documentation of Jdbi's scope. Directories include `jackson2/` and `jackson3/` side by side, `guava/`, `vavr/`, `gson2/`, `moshi/`, `jodatime2/`, `commons-text/`, `guice/`, `spring/` and a separate `spring5/`, plus database specific modules for `postgres/`, `mysql/`, `oracle12/`, `sqlite/` and `postgis/`.
Three modules are worth calling out because they answer questions people usually have. `sqlobject/` and `kotlin-sqlobject/` are the interface driven layer, where an interface method becomes a query. `opentelemetry/` is the tracing plugin. `generator/` is the annotation processor for SQL object types. `jpa/` exists too, which tells you Jdbi is willing to coexist with an ORM rather than asking you to choose.
There is also infrastructure you would not see in a typical library: `benchmark/`, `native-tests/`, `e2e/`, `testcontainers/`, `internal/` and `bom/`. A file named `4.0_TODO` in the tree, alongside `RELEASE_NOTES.md` and `JPMS-SUPPORT.md`, is a plain signal that the next major version is being thought about in the open. An `AI-GUIDELINES.md` at the root is also unusual for a project this age, and suggests contributor guidance is being updated for a newer generation of tooling.
Building with make targets over the Maven wrapper
Jdbi describes itself as batteries included and uses the Apache Maven Wrapper, so the checked-in `mvnw` is what runs. External Maven works too, but the README requires 3.9 or later, and every build task is a `make` target. Installing into your local repository is one command:
$ make installRunning `make` or `make help` lists the targets, and the README is upfront that some of them need project membership privileges. Extra Maven flags go through a variable rather than by editing the Makefile:
% MAVEN_ARGS="-B -fae" make installThe Makefile is readable enough to be worth skimming, because the target names tell you what the project considers important. `tests` depends on `install-notests` and `run-tests`. `install-fast` activates a `fast` profile, and `docs` uses `publish-docs` with javadoc generation enabled. `compare-reproducible` skips tests and japicmp and then runs an artifact comparison, which is how they check that two builds produce the same artifacts. `run-slow-tests` and `native-tests` are separated out for obvious reasons.
Building requires the latest LTS JDK, currently Java 25 per the README, while running requires Java 17 or better. CI runs against Java 17, 21 and 25.
The Java version floor moved twice, and the topic list did not follow
The README keeps a compatibility table for older Java versions, and it is the most quietly consequential paragraph in the file. Java 8, 9 and 10 are supported by any Jdbi version before 3.40.0. Java 11 is supported by any version before 3.50.0. Java 17 or better is required starting with 3.50.0 or newer.
The repository metadata tells a different story. Its topics include `java11`, and its description names Kotlin, Clojure and Scala as languages Jdbi targets. The tree has `kotlin/` and `kotlin-sqlobject/` but no module directory for Clojure or Scala. Both facts are reported, and neither is a reason to distrust the library; they are a reason to trust the README and the tree over the label list.
The practical check for an upgrade is the version number rather than the topic. If you are on 3.49.x you are still on Java 11 and need a plan before moving past 3.50.0. If you assumed Java 11 support from the topic list and you are on 3.55.0, you are running an unsupported configuration. The compatibility rule is documented precisely enough that this should never come as a surprise at build time.
Database and library coverage in CI
The README describes a compatibility policy rather than a single dependency pin, which is unusually clear about how it will break you. Jdbi uses the latest stable release of a library and updates dependencies for releases, and for the listed libraries it also tests the two previous stable versions. The list is Google Guava, Immutables, Jackson, JodaTime, vavr, Google Guice, Kotlin and Spring Framework.
Databases get the same treatment. Jdbi uses PostgreSQL for most of its non-in-memory tests, testing the latest supported Postgres release plus the two previous versions, and it runs tests inside testcontainers against a larger set of databases. Immutables appears in that library list but not in the tree, which is a fair reminder that a compatibility claim can cover a type you would otherwise supply yourself.
Docker is a build requirement for a full release, because a small number of tests use testcontainers. The README lists supported configurations as Docker Desktop on macOS, docker-ce on Linux, and podman 3 or better on Linux and macOS, and it says Colima may work but is untested and unsupported. Two escape hatches exist for local work: `make install-nodocker` skips tests when building and installing locally, and `make tests-nodocker` does the same for running tests alone. `mvnw` itself is at the root, alongside a `bom/` module for consumers who want managed versions.
What the last three releases actually fixed
The release notes read like a record of what real users hit, which is the best signal available about where Jdbi is strong and where it has been sharp edged.
Version 3.53.0 in April 2026 was mostly a security release. The Freemarker configuration allowed templates to construct arbitrary Java types including `freemarker.template.utility.Execute`, so template class resolution was disabled under advisory GHSA-mggx-p7jf-jgw4. The same release upgraded to testcontainers 2.x, which renamed several jar files. That rename matters operationally: `org.testcontainers:jdbc` and `org.testcontainers:junit-jupiter` used to arrive transitively from `jdbi3-testcontainers`, and on 2.x you have to depend on `org.testcontainers:testcontainers-jdbc` and `org.testcontainers:testcontainers-junit-jupiter` explicitly. Jdbi supports both lines.
Version 3.54.0 in July 2026 fixed a deadlock in configuration caching, fixed prepared batch first-time-null binding, and added `@SqlPreflight` as an Alpha annotation for SQL object methods, which runs a literal SQL statement on the same `Handle` with the method's arguments bound before the main statement. That is the shape you want for setting a Postgres session variable such as a trigram threshold. It also updated the postgres driver for CVE-2026-42198.
Version 3.55.0 in September 2026 is the one to read closely if you map objects. It adds binding and mapping of types that are not public, including package-private beans and package-private Immutables value types, and it fixes `KotlinMapper` ignoring a SQL NULL for a `@PropagateNull` constructor parameter or property, which returned 0 or false and mapped the object instead of null. The release also carries a warning about when to set the accessible object strategy: these mappers cache the strategy in effect the first time a type is used, so it has to be set on the `Jdbi` instance before first use, not on a `Handle` or statement.
Editorial conclusion
Jdbi's bet is that the right amount of abstraction over JDBC is small: parameters bound by name or bean, results mapped into your own types, and no ORM hiding the SQL. That bet is why the module list is long while the core stays small, and why plugins like jackson2, jackson3, guava and vavr can add mapping without changing how a query is written. What the README leaves open is the version story: the repository topics still advertise java11 while the README says Java 17 has been required since 3.50.0, and the description names Clojure and Scala support that has no matching module directory in the tree. Trust the README and the module tree over the topic list. Start with the developer guide on jdbi.org and the examples module, then add a mapper plugin only when you actually need a type Jdbi cannot map by itself.
Frequently asked questions
What is JDBI and how is it used in Java?
Jdbi is a library that gives Java and other JVM languages a convenient, idiomatic way to talk to a relational database through JDBC. You write the SQL yourself, bind arguments to it, and map the rows into your own classes, with a Handle holding the connection. The Maven coordinates come from the artifacts under the `core/`, `sqlobject/` and plugin modules in the repository.
Which Java versions can run the current Jdbi release?
Java 17 or better is required starting with Jdbi 3.50.0, and CI runs against Java 17, 21 and 25. Java 11 was supported by any version before 3.50.0, and Java 8, 9 and 10 by any version before 3.40.0. The repository topic list still includes java11, so check the version number rather than the label.
Does Jdbi hide the SQL behind an ORM style API?
No. Jdbi keeps SQL in your code and adds convenience around it, with SQL objects as an optional interface driven layer under `sqlobject/` and `kotlin-sqlobject/`. A `jpa/` module also exists, which means the library is designed to sit alongside an ORM in the same application rather than displace it.
What changed in the Freemarker plugin security fix?
Version 3.53.0 disabled template class resolution because the Freemarker configuration had allowed templates to construct arbitrary Java types, including `freemarker.template.utility.Execute`. The advisory is GHSA-mggx-p7jf-jgw4. The project notes that exploitation needs other unsafe practices such as letting a user dictate template input, and still recommends the change.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/jdbi-jdbi)