Possibly use JDBI - Evolving An Open Source Project presentation for some material
Notes from migrating a small project:
Renamed classes (so not quite as simple as deleting imports and letting the IDE fix it):
DBI
-> Jdbi
IDBI
-> Jdbi
DBIException
-> JdbiException
The constructors for Jdbi
have been replaced with a create()
factory method.
ResultSetMapper
is replaced with RowMapper
and the map
method no longer has the row index. A class named ResultSetMapper
exists in Jdbi 3, but it serves a different purpose. @Mapper
is replaced with @UseRowMapper
. registerMapper()
on Jdbi
is replaced with registerRowMapper()
.
@BindIn
is replaced with @BindList
and no longer requires StringTemplate.
With the default Jdbi templating, angle brackets are not quoted, which means that IntelliJ understands the syntax after you configure the Parameter Pattern under Tools -> Database -> User Patterns.
Query
no longer has a default type of Map
and thus list()
cannot be called on it directly. Call mapToMap()
before calling list()
.
TransactionStatus
no longer exists.
TransactionConsumer.useTransaction()
only takes a Handle
now, so the TransactionStatus
argument needs to be removed when using this with the useTransaction()
methods on Jdbi
or Handle
.
TransactionCallback.inTransaction()
only takes a Handle
now, so the TransactionStatus
argument needs to be removed when using this with the inTransaction()
methods on Jdbi
or Handle
.
CallbackFailedException
no longer exists. The various functional interfaces such as HandleConsumer
, HandleCallback
, TransactionalConsumer
, and TransactionalCallback
, can now throw any exception type (but restricted using generics to avoid needless checked exception handling).
SQL Object support is no longer available by default. It must be registered every created Jdbi
instance.
IntelliJ's Migrate Refactor was helpful to kickstart the migration.
Thanks @electrum for putting this together! This will be a big help
Some additional notes from reviewing my presentation:
java.lang.reflect.Type
, whereas v2 used java.lang.Class
. This means that v3 is capable of handling complex generic type signatures that v2 could not.@Bind
annotations on SQL Object method parameters can be made optional, by compiling your code with the -parameters
flag enabled.StatementLocator
interface is removed from core. All core statements expect to receive the actual SQL now. A similar concept, SqlLocator
was added but only in the realm of SQL Objects.Another one: StatementRewriter
has been refactored into TemplateEngine
and SqlParser
.
Very important to add to the list is the behavior of select. It went from this:
List<Map<String, Object>> rs = h.select("select id, name from something");
To this:
List<Map<String, Object>> rs = h.select("select id, name from something").mapToMap().list();
I wish the extra power and flexibility and safety of v3 didn't come with the price of verbosity.
Hi @javajosh , we didn't consider that particular one to be too bad because we are trying to discourage mapping to Map
objects. If nothing else, the rules around case sensitivity for the keys are confusing. Is there some reason you must emit a Map
rather than creating your own defined type? I personally will always write little result classes (using constructor / field / property mappers and binders) and always avoid using Map
. Do you have some use case where it is very convenient?
Hi @stevenschlansker - I am coming at it from the perspective of "developers first experience". The above code is taken from you're own v2 tutorial, which I think is admirably minimalist. And indeed, with a JVM-hosted language like Groovy, which has a javascript-like map builtin, you'd probably see a non-typed result more often.
@javajosh what do you think of https://github.com/jdbi/jdbi/pull/925 ?
@stevenschlansker Did you mean #928 ?
@stevenschlansker Definitely an improvement! But it's still more verbose than v2. :) This is in addition to the greater verbosity in maven, etc. I just don't want to see JDBI go the way of JUnit which struggled to get people to adopt v4 because it had some nice features, but was far more complicated than v3 and v3 was "good enough". I have that same feeling about the "withHandle" syntax (although I understand your instinct to eliminate all dangling handles).
@javajosh You still have Jdbi.open()
if you want greater control, although we do recommend you use it inside a try-with-resources block for safety.
Starting work on the v2 to v3 migration docs.
@javajosh Coming back to the method ResultBearing.list()
that returns a List<Map<String,Object>>
: I'm not sure adding this was a good idea, especially this late in the release cycle.
I'm empathetic to your concerns about verbosity, but that verbosity serves the purpose of clarifying developer intent:
handle.createQuery(sql)
.mapToMap()
.list()
is clearer to the reader than:
handle.createQuery(sql)
.list()
It's a delicate thing, and I don't envy your position having to choose. JDBI is a nice library, and I'm glad to simply have registered my concerns about verbosity; whether it makes sense to add a convenience method in this specific case, I'm not sure and would tend to trust your judgement over mine, since I'm not seriously involved in the project! Thanks for listening!
Please let us know if you come up with a concrete example of how it's better with a shorter name, or a showcase of how we might improve it 😄
Most helpful comment
Notes from migrating a small project:
Renamed classes (so not quite as simple as deleting imports and letting the IDE fix it):
DBI
->Jdbi
IDBI
->Jdbi
DBIException
->JdbiException
The constructors for
Jdbi
have been replaced with acreate()
factory method.ResultSetMapper
is replaced withRowMapper
and themap
method no longer has the row index. A class namedResultSetMapper
exists in Jdbi 3, but it serves a different purpose.@Mapper
is replaced with@UseRowMapper
.registerMapper()
onJdbi
is replaced withregisterRowMapper()
.@BindIn
is replaced with@BindList
and no longer requires StringTemplate.With the default Jdbi templating, angle brackets are not quoted, which means that IntelliJ understands the syntax after you configure the Parameter Pattern under Tools -> Database -> User Patterns.
Query
no longer has a default type ofMap
and thuslist()
cannot be called on it directly. CallmapToMap()
before callinglist()
.TransactionStatus
no longer exists.TransactionConsumer.useTransaction()
only takes aHandle
now, so theTransactionStatus
argument needs to be removed when using this with theuseTransaction()
methods onJdbi
orHandle
.TransactionCallback.inTransaction()
only takes aHandle
now, so theTransactionStatus
argument needs to be removed when using this with theinTransaction()
methods onJdbi
orHandle
.CallbackFailedException
no longer exists. The various functional interfaces such asHandleConsumer
,HandleCallback
,TransactionalConsumer
, andTransactionalCallback
, can now throw any exception type (but restricted using generics to avoid needless checked exception handling).SQL Object support is no longer available by default. It must be registered every created
Jdbi
instance.IntelliJ's Migrate Refactor was helpful to kickstart the migration.