?
This document uses PHP Chinese website manual Release
DataSourceUtils
作為一個(gè)幫助類提供易用且強(qiáng)大的數(shù)據(jù)庫(kù)訪問(wèn)能力,
我們可以使用該類提供的靜態(tài)
方法從JNDI獲取數(shù)據(jù)庫(kù)連接以及在必要的時(shí)候關(guān)閉之。
它提供支持線程綁定的數(shù)據(jù)庫(kù)連接(比如使用DataSourceTransactionManager
的時(shí)候,將把數(shù)據(jù)庫(kù)連接綁定到當(dāng)前的線程上)。
SmartDataSource
是DataSource
接口的一個(gè)擴(kuò)展,用來(lái)提供數(shù)據(jù)庫(kù)連接。使用該接口的類在指定的操作之后可以檢查是否需要關(guān)閉連接。該接口在某些情況下非常有用,比如有些情況需要重用數(shù)據(jù)庫(kù)連接。
AbstractDataSource
是一個(gè)實(shí)現(xiàn)了DataSource
接口的abstract
基類。它實(shí)現(xiàn)了DataSource
接口的
一些無(wú)關(guān)痛癢的方法,如果你需要實(shí)現(xiàn)自己的DataSource
,那么可以繼承該類。
SingleConnectionDataSource
是SmartDataSource
接口
的一個(gè)實(shí)現(xiàn),其內(nèi)部包裝了一個(gè)單連接。該連接在使用之后將不會(huì)關(guān)閉,很顯然它不能在多線程的環(huán)境下使用。
當(dāng)客戶端代碼調(diào)用close方法的時(shí)候,如果它總是假設(shè)數(shù)據(jù)庫(kù)連接來(lái)自連接池(就像使用持久化工具時(shí)一樣),
你應(yīng)該將suppressClose
設(shè)置為true。這樣,通過(guò)該類獲取的將是代理連接(禁止關(guān)閉)而不是原有的物理連接。
需要注意的是,我們不能把使用該類獲取的數(shù)據(jù)庫(kù)連接造型(cast)為Oracle Connection之類的本地?cái)?shù)據(jù)庫(kù)連接。
SingleConnectionDataSource
主要在測(cè)試的時(shí)候使用。它使得測(cè)試代碼很容易脫離應(yīng)用服務(wù)器而在一個(gè)簡(jiǎn)單的JNDI環(huán)境下運(yùn)行。
與DriverManagerDataSource
不同的是,它始終只會(huì)使用同一個(gè)數(shù)據(jù)庫(kù)連接,從而避免每次建立物理連接的開(kāi)銷。
DriverManagerDataSource
類實(shí)現(xiàn)了
SmartDataSource
接口??梢允褂胋ean properties來(lái)設(shè)置JDBC Driver屬性,該類每次返回的都是一個(gè)新的連接。
該類主要在測(cè)試以及脫離J2EE容器的獨(dú)立環(huán)境中使用。它既可以用來(lái)在application context中作為一個(gè)DataSource
bean,也可以在簡(jiǎn)單的JNDI環(huán)境下使用。
由于Connection.close()
僅僅只是簡(jiǎn)單的關(guān)閉數(shù)據(jù)庫(kù)連接,因此任何能夠獲取DataSource
的持久化代碼都能很好的工作。不過(guò)使用JavaBean風(fēng)格的連接池
(比如commons-dbcp)也并非難事。即使是在測(cè)試環(huán)境下,使用連接池也是一種比使用DriverManagerDataSource
更好的做法。
TransactionAwareDataSourceProxy
作為目標(biāo)DataSource
的一個(gè)代理,
在對(duì)目標(biāo)DataSource
包裝的同時(shí),還增加了Spring的事務(wù)管理能力,
在這一點(diǎn)上,這個(gè)類的功能非常像J2EE服務(wù)器所提供的事務(wù)化的JNDI DataSource
。
該類幾乎很少被用到,除非現(xiàn)有代碼在被調(diào)用的時(shí)候需要一個(gè)標(biāo)準(zhǔn)的 JDBC DataSource
接口實(shí)現(xiàn)作為參數(shù)。
這種情況下,這個(gè)類可以使現(xiàn)有代碼參與Spring的事務(wù)管理。通常最好的做法是使用更高層的抽象
來(lái)對(duì)數(shù)據(jù)源進(jìn)行管理,比如JdbcTemplate
和DataSourceUtils
等等。
如果需要更詳細(xì)的資料,請(qǐng)參考 TransactionAwareDataSourceProxy
JavaDocs。
DataSourceTransactionManager
類是
PlatformTransactionManager
接口的一個(gè)實(shí)現(xiàn),用于處理單JDBC數(shù)據(jù)源。
它將從指定DataSource取得的JDBC連接綁定到當(dāng)前線程,因此它也支持了每個(gè)數(shù)據(jù)源對(duì)應(yīng)到一個(gè)線程。
我們推薦在應(yīng)用代碼中使用DataSourceUtils.getConnection(DataSource)
來(lái)獲取
JDBC連接,而不是使用J2EE標(biāo)準(zhǔn)的DataSource.getConnection
。因?yàn)榍罢邔伋? unchecked的org.springframework.dao
異常,而不是checked的
SQLException
異常。Spring Framework中所有的類(比如
JdbcTemplate
)都采用這種做法。如果不需要和這個(gè)
DataSourceTransactionManager
類一起使用,DataSourceUtils
提供的功能跟一般的數(shù)據(jù)庫(kù)連接策略沒(méi)有什么兩樣,因此它可以在任何場(chǎng)景下使用。
DataSourceTransactionManager
類支持定制隔離級(jí)別,以及對(duì)SQL語(yǔ)句查詢超時(shí)的設(shè)定。
為了支持后者,應(yīng)用代碼必須使用JdbcTemplate
或者在每次創(chuàng)建SQL語(yǔ)句時(shí)調(diào)用DataSourceUtils.applyTransactionTimeout(..)
方法。
在使用單個(gè)數(shù)據(jù)源的情形下,你可以用DataSourceTransactionManager
來(lái)替代JtaTransactionManager
,
因?yàn)?code class="classname">DataSourceTransactionManager不需要容器支持JTA。如果你使用DataSourceUtils.getConnection(DataSource)
來(lái)獲取
JDBC連接,二者之間的切換只需要更改一些配置。最后需要注意的一點(diǎn)就是JtaTransactionManager
不支持隔離級(jí)別的定制!
有時(shí)我們需要執(zhí)行特殊的,由特定廠商提供的與標(biāo)準(zhǔn)JDBC的API不同的JDBC方法。此時(shí),當(dāng)我們?cè)谀硞€(gè)應(yīng)用服務(wù)器上運(yùn)行包裝了這些廠商各自實(shí)現(xiàn)的Connection
, Statement
和ResultSet
對(duì)象的DataSource
時(shí),可能會(huì)遇到一些問(wèn)題。如果你要訪問(wèn)這些對(duì)象,你可以配置一個(gè)包含NativeJdbcExtractor
的JdbcTemplate
或者OracleLobHandler
。
NativeJdbcExtractor根據(jù)執(zhí)行環(huán)境的不同,會(huì)有不同的風(fēng)格的實(shí)現(xiàn):
SimpleNativeJdbcExtractor
C3P0NativeJdbcExtractor
CommonsDbcpNativeJdbcExtractor
JBossNativeJdbcExtractor
WebLogicNativeJdbcExtractor
WebSphereNativeJdbcExtractor
XAPoolNativeJdbcExtractor
通常來(lái)說(shuō)SimpleNativeJdbcExtractor
類對(duì)于絕大多數(shù)環(huán)境,已經(jīng)足以屏蔽 Connection
對(duì)象。可以參見(jiàn)Java Docs獲取詳細(xì)信息。