Search code examples
spring-dataspring-jdbcspring-data-jdbc

Usage guidelines for JDBC with Spring


So recently there´s a new player in the Spring JDBC eco system: JdbcClient
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/jdbc/core/simple/JdbcClient.html

We also (still) got this:
JdbcTemplate
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/jdbc/core/JdbcTemplate.html

Beside that we already got:
Spring Data Jdbc
https://spring.io/projects/spring-data-jdbc

And today i saw this:
JdbcOperations
https://github.com/spring-projects/spring-modulith/blob/main/spring-modulith-events/spring-modulith-events-jdbc/src/main/java/org/springframework/modulith/events/jdbc/JdbcEventPublicationRepository.java#L32

While i usually go with Spring Data Jdbc (which is absolutely great by the way) i wonder why there is so much Jdbc (let`s say) stuff around?

As far as i can see there is everything you need (JDBC related) already shipped in Spring Data JDBC.

So i´m curious to know what kind of problems are you expected to solve with the new JdbcClient?
Futhermore: why is this even there?

I mean the whole Spring Data JDBC library isn't that much space wasted (as one might argument), isn`t it?

And why is there a JdbcOperations?

I`m kind of confused on where the (jdbc) journey is going in the spring ecosystem?


Solution

  • I recommend reading through https://docs.spring.io/spring-framework/reference/data-access/jdbc/core.html for more details.

    But here is an overview starting from the lowest level of abstraction.

    JdbcTemplate

    JdbcTemplate is actually an implementation of JdbcOperations Everything is build on those. Make JDBC just a little bit easier to use, by:

    • abstracting away Exception handling. Ever tried to properly handle exceptions for JDBC method calls, that need clean up which in turn might throw the same kind of exception? Don't use a JdbcTemplate instead.

    • delegating the extraction of data from a ResultSet into ResultSetExtractor, RowMapper and ResultSetExtractor

    • simplifying many typical use cases, like executing a query and getting the result as a List<Object>

    But you still provide the SQL you want to execute and the JdbcTemplate does very little with that SQL. (It actually does some replacements for collection like parameters)

    NamedParameterJdbcTemplate

    NamedParameterJdbcTemplate implements NamedParameterJdbcOperations and is build on top of JdbcOperations.

    It allows you to use named parameters, i.e. things like :myval in your SQL statements instead of the standard JDBC ? placeholder.

    All the classes mentioned so far are really old. They exist since Spring 2.0 or before. JdbcTemplate has a @since May 3, 2001!

    JdbcClient

    JdbcClient offers a fluent interface and is a fairly new addition. It offers most of the capabilities of NamedParameterJdbcOperations and JdbcOperations with a fluent interface.

    In order to do that it actually uses NamedParameterJdbcOperations and JdbcOperations under the hood.

    Spring Data JDBC

    Spring Data JDBC is an ORM based on the ideas of Domain Driven Design. This means you create entity classes and Spring Data JDBC will create and execute SQL for you to persist, find and load such entities. You use Repositories for interacting with the database which you declare as interfaces and Spring Data will provide implementations. For simple use cases you won't have to write any SQL at all.

    Agains Spring Data JDBC is build on the classes mentioned above, especially NamedParameterJdbcOperations

    What should I use?

    1. If you just want to execute some SQL use a JdbcClient. It is nice to use and in most cases will be up to the job.

    2. If you need one of the features not supported by JdbcClient, or if you don't like a fluent interface fall back on JdbcOperations or NamedParameterJdbcOperations or some other class. The reference documentation has this not about the topic:

      JdbcClient is a flexible but simplified facade for JDBC query/update statements. Advanced capabilities such as batch inserts and stored procedure calls typically require extra customization: consider Spring’s SimpleJdbcInsert and SimpleJdbcCall classes or plain direct JdbcTemplate usage for any such capabilities not available in JdbcClient.

    3. If you need an ORM, because you have a rich object model that needs to be persisted to a database use Spring Data JDBC

    4. Mix all the options from above. Since everything eventually uses a JdbcTemplate you can have instances of all these classes in your program and use the matching one for each individual use case.