DataSourceUtils
作为一个帮助类提供易用且强大的数据库访问能力,
我们可以使用该类提供的静态
方法从JNDI获取数据库连接以及在必要的时候关闭之。
它提供支持线程绑定的数据库连接(比如使用DataSourceTransactionManager
的时候,将把数据库连接绑定到当前的线程上)。
注:getDataSourceFromJndi(..)
方法主要用于那些没有使用bean factory
或者application context的场合。如果使用application context,那么最好是在
JndiObjectFactoryBean
中配置bean或者直接使用
JdbcTemplate
实例。JndiObjectFactoryBean
能够通过JNDI获取DataSource
并将
DataSource
作为引用参数传递给其他bean。
这样,在不同的DataSource
之间切换只需要修改配置文件即可,
甚至我们可以用一个非JNDI的DataSource
来替换
FactoryBean
定义!
SmartDataSource
是DataSource
接口的一个扩展,用来提供数据库连接。使用该接口的类在指定的操作之后可以检查是否需要关闭连接。
该接口在某些情况下非常有用,比如有些情况需要重用数据库连接。
AbstractDataSource
是一个实现了DataSource
接口的abstract
基类。它实现了DataSource
接口的
一些无关痛痒的方法,如果你需要实现自己的DataSource
,那么继承
该类是个好主意。
SingleConnectionDataSource
是SmartDataSource
接口
的一个实现,其内部包装了一个单连接。该连接在使用之后将不会关闭,很显然它不能在多线程
的环境下使用。
当客户端代码调用close方法的时候,如果它总是假设数据库连接来自连接池(就像使用持久化工具时一样),
你应该将suppressClose
设置为true。
这样,通过该类获取的将是代理连接(禁止关闭)而不是原有的物理连接。
需要注意的是,我们不能把使用该类获取的数据库连接造型(cast)为Oracle Connection之类的本地数据库连接。
SingleConnectionDataSource
主要在测试的时候使用。
它使得测试代码很容易脱离应用服务器而在一个简单的JNDI环境下运行。
与DriverManagerDataSource
不同的是,它始终只会使用同一个数据库连接,
从而避免每次建立物理连接的开销。
DriverManagerDataSource
类实现了
SmartDataSource
接口。在applicationContext.xml中可以使用
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
JavaDoc 。
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
不支持隔离级别的定制!