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.
Spring caching support using maps needs to be enabled.
On the configuration:
or in XML:
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
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.
@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.
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.
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.
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
The maps’ key being the column name, and its value the database’ value
RowMapperinterface 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,
RowMappercan be replaced by a Lambda.
RowCallbackHandlerif no object shall be returned, meaning you process the resultsets’ rows by implementing the
processRowmethod but do not return anything.
ResultSetExtractorreceives 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.