Using Spring JdbcTemplate Instead of Object-Relational Mapping

Home » Blog » Software » Using Spring JdbcTemplate Instead of Object-Relational Mapping

Spring JDBC and Spring JdbcTemplate in particular has become my go-to tool for accessing relational databases for quite some time now and for good reason in my opinion:

The common way for using data from an RDBMS in an object-oriented context used to be and for the most part still is object-relational mapping (ORM) frameworks like the Java Persistence API (JPA) or RailsActiveRecord. As the name suggests these frameworks attempt to map data (and concepts) from relational, set-oriented data structures, which are common in database systems, to the object-oriented patterns predominantly used in application development today.

While certainly useful in that they allow you to use a reliable and scalable relational database as data storage for your application these frameworks face an unavoidable impedance mismatch. They often provide leaky abstractions at best by papering over the fundamental mathematical differences between sets (relational) and graphs (object-oriented). This impedance mismatch will always be there. You can gloss over it to some extent but it’ll crop up every now and then.

Therefore it’s a good idea we don’t fight this discrepancy but embrace it and keep the systems dealing with objects and sets as simple as possible by not trying to force object-orientation on relations and vice versa.

This is where JdbcTemplate comes in handy. Instead of defining rigid database mappings it allows you to have ordinary, native and flexible SQL queries like this in your code:


...

List<SomeEntity> entities =
        jdbcTemplate.query(
            "SELECT a.title, b.text FROM a JOIN b ON b.id = a.id",
            new SomeEntityMapper()
        );

...

This query uses a mapper class that implements org.springframework.jdbc.core.RowMapper and for example could like look this:


public class SomeEntitykMapper implements RowMapper<SomeEntity> {
    public SomeEntity mapRow(ResultSet rs, int rowNum) throws SQLException {
        SomeEntity someEntity = new SomeEntity();

        someEntity.setId(rs.getInt("id"));
        someEntity.setTitle(rs.getString("title"));
        someEntity.setText(rs.getString("text"));
        
        return someEntity;
    }
}

This technique allows for flexible mapping between relational data and an object-oriented representation. If the class’ field names and the result set’s column names match you can even use a BeanRowPropertyMapper and do without the custom mapper altogether.

Leave a Comment

* Checkbox GDPR is required

*

I agree

By continuing to browse the site you agree to our use of cookies. Privacy Policy

Privacy Preference Center

Strictly necessary

These cookies are necessary for the site to function.

PHPSESSID: Preserves user session state across page requests.

__cfduid: Used by the content network, Cloudflare, to identify trusted web traffic.

PHPSESSID
__cfduid

Preferences

Remembers the user's submitted data when a comment is submitted in a blog post. The purpose is to aut o-populate form fields for subsequent comments, in order to save time for the user.

wfvt_#

Statistics

Statistic cookies help us to understand how visitors interact with our websites by collecting and reporting information anonymously.

_ga: Registers a unique ID that is used to generate statistical data on how the visitor uses the website.

_gat: Used by Google Analytics to throttle request rate.

_gid: Registers a unique ID that is used to generate statistical data on how the visitor uses the website.

collect: Used to send data to Google Analytics about the visitor's device and behaviour. Tracks the visitor across d evices and marketing channels.

_ga,_gat,_gid
collect

Security

We use Wordfence to secure our website against hacking attempts: https://www.wordfence.com/

wordfence_verifiedHuman

Close your account?

Your account will be closed and all data will be permanently deleted and cannot be recovered. Are you sure?