Data Access With Spring

Spring provides many supportive tools for data management. For example, when manipulating databases you might want to rely on transaction management.

When you annotate a method with @Transactional a transaction must be present before method-execution. To match this requirement, Spring proxies your class with a transaction interceptor that uses a transaction manager to administer the transaction.

Transactions are put in thread-local storage of the transaction manager. Other resources like the JdbcTemplate then finds it automatically if needed.

See separate post on transaction management with Spring for more details.

Spring throws runtime (unchecked) exceptions to be independant of checked exceptions thrown by infrastructure implementations.

For example sql-error-codes are defined in the sql-error-codes.xml in spring-jdbc.jar covering all codes for different databases.

Caching support

Spring caching support using maps needs to be enabled.

On the configuration:
@EnableCaching
or in XML:
<cache:annotation-driven />

Then, specify a cache manager bean. You can write your own, or use an existing one. For example SimpleCacheManager where you define the caches and their names, which you reference in the value-attribute of the @Cacheable annotation.
Third-party cache managers can also be used, e.g. EhCacheManager, retrieved from a EhCacheManagerFactoryBean and wrapped in a <code>EhCacheCacheManager or Gemfire a “distributed, shared nothing data-grid” that offers cache replication across multiple nodes.

Caching values

@Cacheable(value="...", key="SpEl", condition="SpEl")
can be used for method-calls that will always return the same result for the same arguments. A unique key can be defined using SpEl on the arguments.
They key then is used for the caching map. The maps’ name has also to be defined, as multiple caches can be used. If only certain results shall be cached, the condition
defines the rule whether or not to.

@CacheEvict(value="...") clears the referenced cache before method-invocation.

JDBC

For several use cases, Spring provides templates, one of them is JDBC. Templates prevent code redundancy, they are configurable, let you work with the result (provide a callback object with your own code) and provide exception handling.

The JdbcTemplate is thread safe, it acquires the connection, participates in the transaction, executes the statement, processes the result set and releases the connection – all this stuff you do not have to worry about. You need one template per database, as the data source is a constructor argument.

Querying

The query string may contain “?” as placeholder(s) for arguments provided with the query-method.

Simple types can be retrieved by using
jdbcTemplate.queryforObject([sql-statement], [arguments, if any], [Type].class);

A single row is queried using queryForMap(...) while for multiple rows queryForList(...) is used, where every entry represents a row in form of a Map<String, Object>.

The maps’ key being the column name, and its value the database’ value

Object mapping

  • RowMapper interface for mapping every single row to a domain object. It does not matter, if the queries intention is to return a single row or multiple rows
    With Java 8, RowMapper can be replaced by a Lambda.
  • RowCallbackHandler if no object shall be returned, meaning you process the resultsets’ rows by implementing the processRow method but do not return anything.
  • ResultSetExtractor receives the whole result-set for you to iterate over and mapping multiple rows to a single object. For these two is a shorter Java 8 notation using Lambdas available as well.

jdbcTemplate.update([sql-statement], args...) processes both insert- and update-statements.

Bing Bong

Guest Author - Knows Java and Spring very well.

Latest posts by Bing Bong (see all)

Leave a Reply

Your email address will not be published. Required fields are marked *

*