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 theprocessRow
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.