The main purpose of this note is to show how to use Jdbi with Java records, given a Java record is not a JavaBean - and therefore you cannot rely on some of the more traditional approaches to using Jdbi.
Assume the following table (in this case, for MySQL 8):
|
|
The Java code uses Maven with the following Jdbi dependencies:
|
|
Note the dependency for jdbi3-sqlobject
. This is a plug-in, which will need to be installed in your jdbi
object, later on - see below.
(Read more about the SQL Objects extension.)
For our simple demo, the Java record is defined as follows:
|
|
For simplicity, this relies on Jdbi’s ability to automatically translate snake-case column names such as country_code
to camel-case field names such as countryCode
. (We need to do this for Java records, since we cannot annotate the record’s getters/setters with @ColumnName
. A Java record is not a JavaBean.)
I will assume you have already created your org.jdbi.v3.core.Jdbi
instance in the usual way - typically using a connection pool - so, something like:
|
|
The Jdbi object needs to have the jdbi3-sqlobject
plugin installed:
|
|
This uses the org.jdbi.v3.sqlobject.SqlObjectPlugin
class.
Side note: I typically also need this config option (but this is not directly relevant to this discussion):
|
|
There are various ways you can use the plugin. Here is a minimal example showing one way:
First create a new interface:
|
|
Note the @BindMethods
annotation which allows Jdbi to use the fields in our country
instance and map them to the table’s columns for us.
To use this interface, do the following:
|
|
This allows Jdbi to generate implementations of the methods provided in that interface. Jdbi does all this for you - you do not need to provide your own implementations of the method stubs in the interface (in this specific example). This is not the only way to do this, but I think it’s the simplest - using the least amount of code.
Our generated method can then be invoked as follows:
|
|
To select all records from the table, you can add the following method stub to the interface:
|
|
And then use it as follows:
|
|
In this case we needed to use the @RegisterConstructorMapper
annotation to allow Jdbi to invoke our Java record’s constructor, by automatically mapping the table’s column names to the record’s field names.
(You can, of course, use Jdbi bind parameters to create SQL statements using where
clauses, together with your Java records.)
For alternative approaches see the Jdbi documentation. Specifically, note the caveats mentioned here regarding the use of onDemand()
:
The performance of on-demand objects depends on the database and database connection pooling. For performance critical operations, it may be better to manage the handle manually and use attached objects.
Overall, this is a remarkably small amount of code.
Background reading: Make sure record types work.