DataSourceUtils
作为一个帮助类提供易用且强大的数据库访问能力,
我们可以使用该类提供的静态
方法从JNDI获取数据库连接以及在必要的时候关闭之。
它提供支持线程绑定的数据库连接(比如使用DataSourceTransactionManager
的时候,将把数据库连接绑定到当前的线程上)。
SmartDataSource
是DataSource
接口的一个扩展,用来提供数据库连接。使用该接口的类在指定的操作之后可以检查是否需要关闭连接。该接口在某些情况下非常有用,比如有些情况需要重用数据库连接。
AbstractDataSource
是一个实现了DataSource
接口的abstract
基类。它实现了DataSource
接口的
一些无关痛痒的方法,如果你需要实现自己的DataSource
,那么可以继承该类。
SingleConnectionDataSource
是SmartDataSource
接口
的一个实现,其内部包装了一个单连接。该连接在使用之后将不会关闭,很显然它不能在多线程的环境下使用。
当客户端代码调用close方法的时候,如果它总是假设数据库连接来自连接池(就像使用持久化工具时一样),
你应该将suppressClose
设置为true。这样,通过该类获取的将是代理连接(禁止关闭)而不是原有的物理连接。
需要注意的是,我们不能把使用该类获取的数据库连接造型(cast)为Oracle Connection之类的本地数据库连接。
SingleConnectionDataSource
主要在测试的时候使用。它使得测试代码很容易脱离应用服务器而在一个简单的JNDI环境下运行。
与DriverManagerDataSource
不同的是,它始终只会使用同一个数据库连接,从而避免每次建立物理连接的开销。
DriverManagerDataSource
类实现了
SmartDataSource
接口。可以使用bean properties来设置JDBC Driver属性,该类每次返回的都是一个新的连接。
该类主要在测试以及脱离J2EE容器的独立环境中使用。它既可以用来在application context中作为一个DataSource
bean,也可以在简单的JNDI环境下使用。
由于Connection.close()
仅仅只是简单的关闭数据库连接,因此任何能够获取DataSource
的持久化代码都能很好的工作。不过使用JavaBean风格的连接池
(比如commons-dbcp)也并非难事。即使是在测试环境下,使用连接池也是一种比使用DriverManagerDataSource
更好的做法。
TransactionAwareDataSourceProxy
作为目标DataSource
的一个代理,
在对目标DataSource
包装的同时,还增加了Spring的事务管理能力,
在这一点上,这个类的功能非常像J2EE服务器所提供的事务化的JNDI DataSource
。
注意
该类几乎很少被用到,除非现有代码在被调用的时候需要一个标准的 JDBC DataSource
接口实现作为参数。
这种情况下,这个类可以使现有代码参与Spring的事务管理。通常最好的做法是使用更高层的抽象
来对数据源进行管理,比如JdbcTemplate
和DataSourceUtils
等等。
如果需要更详细的资料,请参考 TransactionAwareDataSourceProxy
JavaDocs。
DataSourceTransactionManager
类是
PlatformTransactionManager
接口的一个实现,用于处理单JDBC数据源。
它将从指定DataSource取得的JDBC连接绑定到当前线程,因此它也支持了每个数据源对应到一个线程。
我们推荐在应用代码中使用DataSourceUtils.getConnection(DataSource)
来获取
JDBC连接,而不是使用J2EE标准的DataSource.getConnection
。因为前者将抛出
unchecked的org.springframework.dao
异常,而不是checked的
SQLException
异常。Spring Framework中所有的类(比如
JdbcTemplate
)都采用这种做法。如果不需要和这个
DataSourceTransactionManager
类一起使用,DataSourceUtils
提供的功能跟一般的数据库连接策略没有什么两样,因此它可以在任何场景下使用。
DataSourceTransactionManager
类支持定制隔离级别,以及对SQL语句查询超时的设定。
为了支持后者,应用代码必须使用JdbcTemplate
或者在每次创建SQL语句时调用DataSourceUtils.applyTransactionTimeout(..)
方法。
在使用单个数据源的情形下,你可以用DataSourceTransactionManager
来替代JtaTransactionManager
,
因为DataSourceTransactionManager
不需要容器支持JTA。如果你使用DataSourceUtils.getConnection(DataSource)
来获取
JDBC连接,二者之间的切换只需要更改一些配置。最后需要注意的一点就是JtaTransactionManager
不支持隔离级别的定制!
有时我们需要执行特殊的,由特定厂商提供的与标准JDBC的API不同的JDBC方法。此时,当我们在某个应用服务器上运行包装了这些厂商各自实现的Connection
, Statement
和ResultSet
对象的DataSource
时,可能会遇到一些问题。如果你要访问这些对象,你可以配置一个包含NativeJdbcExtractor
的JdbcTemplate
或者OracleLobHandler
。
NativeJdbcExtractor根据执行环境的不同,会有不同的风格的实现:
SimpleNativeJdbcExtractor
C3P0NativeJdbcExtractor
CommonsDbcpNativeJdbcExtractor
JBossNativeJdbcExtractor
WebLogicNativeJdbcExtractor
WebSphereNativeJdbcExtractor
XAPoolNativeJdbcExtractor
通常来说SimpleNativeJdbcExtractor
类对于绝大多数环境,已经足以屏蔽 Connection
对象。可以参见Java Docs获取详细信息。