Spring obtains a connection to the database through a
DataSource
. A
DataSource
is part of the JDBC
specification and is a generalized connection factory. It allows a
container or a framework to hide connection pooling and transaction
management issues from the application code. As a developer, you need
not know details about how to connect to the database; that is the
responsibility of the administrator that sets up the datasource. You
most likely fill both roles as you develop and test code, but you do not
necessarily have to know how the production data source is
configured.
When using Spring's JDBC layer, you obtain a data source from JNDI or you configure your own with a connection pool implementation provided by a third party. Popular implementations are Apache Jakarta Commons DBCP and C3P0. Implementations in the Spring distribution are meant only for testing purposes and do not provide pooling.
This section uses Spring's
DriverManagerDataSource
implementation, and
several additional implementations are covered later.
Note | |
---|---|
Only use the |
You obtain a connection with
DriverManagerDataSource
as you typically obtain a
JDBC connection. Specify the fully qualified classname of the JDBC
driver so that the DriverManager
can load the
driver class. Next, provide a URL that varies between JDBC drivers.
(Consult the documentation for your driver for the correct value.) Then
provide a username and a password to connect to the database. Here is an
example of how to configure a
DriverManagerDataSource
in Java code:
DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("org.hsqldb.jdbcDriver"); dataSource.setUrl("jdbc:hsqldb:hsql://localhost:"); dataSource.setUsername("sa"); dataSource.setPassword("");
Here is the corresponding XML configuration:
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="${jdbc.driverClassName}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean> <context:property-placeholder location="jdbc.properties"/>
The following examples show the basic connectivity and configuration for DBCP and C3P0. To learn about more options that help control the pooling features, see the product documentation for the respective connection pooling implementations.
DBCP configuration:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${jdbc.driverClassName}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean> <context:property-placeholder location="jdbc.properties"/>
C3P0 configuration:
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass" value="${jdbc.driverClassName}"/> <property name="jdbcUrl" value="${jdbc.url}"/> <property name="user" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean> <context:property-placeholder location="jdbc.properties"/>
The DataSourceUtils
class is a convenient
and powerful helper class that provides static
methods to obtain connections from JNDI and close connections if
necessary. It supports thread-bound connections with, for example,
DataSourceTransactionManager
.
The SmartDataSource
interface
should be implemented by classes that can provide a connection to a
relational database. It extends the
DataSource
interface to allow classes
using it to query whether the connection should be closed after a given
operation. This usage is efficient when you know that you will reuse a
connection.
is an
AbstractDataSource
base class for
Spring's abstract
DataSource
implementations that
implements code that is common to all DataSource
implementations.
You extend the AbstractDataSource
class if you
are writing your own DataSource
implementation.
The SingleConnectionDataSource
class is an
implementation of the SmartDataSource
interface that wraps a single
Connection
that is
not closed after each use. Obviously, this is not
multi-threading capable.
If any client code calls close in the
assumption of a pooled connection, as when using persistence tools, set
the suppressClose
property to
true
. This
setting returns a close-suppressing proxy wrapping the physical
connection. Be aware that you will not be able to cast this
to a native Oracle Connection
or the like
anymore.
This is primarily a test class. For example, it enables easy
testing of code outside an application server, in conjunction with a
simple JNDI environment. In contrast to
DriverManagerDataSource
, it reuses the same
connection all the time, avoiding excessive creation of physical
connections.
The DriverManagerDataSource
class is an
implementation of the standard DataSource
interface that configures a plain JDBC driver through bean properties,
and returns a new Connection
every
time.
This implementation is useful for test and stand-alone
environments outside of a Java EE container, either as a
DataSource
bean in a Spring IoC
container, or in conjunction with a simple JNDI environment.
Pool-assuming Connection.close()
calls will simply
close the connection, so any
DataSource
-aware persistence code should
work. However, using JavaBean-style connection pools such as
commons-dbcp
is so easy, even in a test environment, that
it is almost always preferable to use such a connection pool over
DriverManagerDataSource
.
TransactionAwareDataSourceProxy
is a proxy
for a target DataSource
, which wraps that
target DataSource
to add awareness of
Spring-managed transactions. In this respect, it is similar to a
transactional JNDI DataSource
as provided
by a Java EE server.
Note | |
---|---|
It is rarely desirable to use this class, except when already
existing code that must be called and passed a standard JDBC
|
(See the
TransactionAwareDataSourceProxy
Javadocs for more
details.)
The DataSourceTransactionManager
class is a
PlatformTransactionManager
implementation
for single JDBC datasources. It binds a JDBC connection from the
specified data source to the currently executing thread, potentially
allowing for one thread connection per data source.
Application code is required to
retrieve the JDBC connection through
DataSourceUtils.getConnection(DataSource)
instead of
Java EE's standard DataSource.getConnection
. It
throws unchecked org.springframework.dao
exceptions
instead of checked SQLExceptions
. All
framework classes like JdbcTemplate
use this
strategy implicitly. If not used with this transaction manager, the
lookup strategy behaves exactly like the common one - it can thus be
used in any case.
The DataSourceTransactionManager
class
supports custom isolation levels, and timeouts that get applied as
appropriate JDBC statement query timeouts. To support the latter,
application code must either use JdbcTemplate
or
call the DataSourceUtils.applyTransactionTimeout(..)
method for each created statement.
This implementation can be used instead of
JtaTransactionManager
in the single resource
case, as it does not require the container to support JTA. Switching
between both is just a matter of configuration, if you stick to the
required connection lookup pattern. JTA does not support custom
isolation levels!
Sometimes you need to access vendor specific JDBC methods that
differ from the standard JDBC API. This can be problematic if you are
running in an application server or with a
DataSource
that wraps the
Connection
, Statement
and
ResultSet
objects with its own wrapper objects.
To gain access to the native objects you can configure your
JdbcTemplate
or
OracleLobHandler
with a
NativeJdbcExtractor
.
The NativeJdbcExtractor
comes in a variety of flavors
to match your execution environment:
SimpleNativeJdbcExtractor
C3P0NativeJdbcExtractor
CommonsDbcpNativeJdbcExtractor
JBossNativeJdbcExtractor
WebLogicNativeJdbcExtractor
WebSphereNativeJdbcExtractor
XAPoolNativeJdbcExtractor
Usually the SimpleNativeJdbcExtractor
is
sufficient for unwrapping a Connection
object in
most environments. See the Javadocs for more details.