Spring 6.1 introduces RestClient
, a blocking variant of WebClient
.
I would like a modern JDBC client like R2DBC's DatabaseClient
as well.
Like RestTemplate
, JdbcTemplate
also has many overloaded method, making it difficult to add new functionality. (For example, Optional
support https://github.com/spring-projects/spring-framework/issues/30927) Like RestClient
for RestTemplate
, JdbcClient
for JdbcTemplate
with fluent api would make it easier to add modern features.
Comment From: jhoeller
As per my comment on #https://github.com/spring-projects/spring-framework/issues/30927#issuecomment-1647458825, this is to be investigated for 6.1 now. If we are happy with an initial cut, I can see this being included in 6.1 M4 already.
Comment From: jhoeller
This is coming into 6.1 M4 as org.springframework.jdbc.core.simple.JdbcClient
now, as a unified facade for JdbcTemplate
and NamedParameterJdbcTemplate
with flexible parameter options as well as flexible result retrieval options. For example:
Optional<Integer> value = client.sql("SELECT AGE FROM CUSTMR WHERE ID = :id")
.param("id", 3)
.query((rs, rowNum) -> rs.getInt(1))
.optional();
Comment From: jhoeller
For a first impression, here is the entire JdbcClient
API: https://github.com/spring-projects/spring-framework/blob/main/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/JdbcClient.java
Comment From: making
I migrated 2 projects to JdbcClient
. Both are in production :)
https://github.com/categolj/blog-api/commit/b2303dec597262cf221db0e3cfac884768c83fa9 https://github.com/categolj/note-api/commit/5d5ecc36dbf6a13fe5efca9ed2333ef60b65e2e9
The migration was very smooth and all tests passed without any changes. I love this client. Thank you for making this happen!
Comment From: jhoeller
A heads-up that the query
variants have slightly changed along with #26594: There is a new query(Class)
method with value and property mapping support now, as an alternative to specifying a custom RowMapper
instance. Since this also covers typed column mappings, the singleColumn
/singleValue
methods are declared without a Class
parameter now and just return whatever ResultSet.getObject
provided (analogous to the existing singleRow
method).
Note that singleColumn
/singleValue
typing only works for the actual result type now, there is no coercion/conversion anymore (like on all other methods on the query()
result spec). So e.g. to get an Integer
, do .query(Integer.class).single()
instead of the former .query().singleValue(Integer.class)
.