公告
問題虛擬背景:
A項目組要實現一個基于Sql Server的應用,但工作環境只安裝有MySql(公司對開源比較看好: )),而且客戶有可能會轉移到Oracle數據庫環境。要求應用具有數據庫移植能力和快速更換能力,使應用在工作環境調試成功后能迅速轉移到客戶的Sql Server環境,而且將來可以方便地轉向Oracle。
Andy提出的可用方案:
1、使用標準JDBC
2、使用抽象類定義數據訪問單元
3、定義具體數據源訪問單元繼承2中接口
代碼示例:
定義數據訪問單元抽象類,包含數據訪問邏輯
定義具體數據源訪問單元
在調用數據訪問層時,可以聲明一個DataManager的引用,然后在構造器中實例化為具體子類,如:
以后要遷移到另一個數據庫(有JDBC驅動),只需定義具體子類繼承DataManager(如HsqlDataManager),然后修改資源文件中的DataManager名稱(或者將new的類名改一下),不需要修改代碼。
這興許可以解釋另一個問題:不贊成使用存儲過程,而應將SQL語句嵌在代碼中(適用于Java;微軟注定.Net不會有平臺移植性,數據庫大都用Sql Server,所以寫存儲過程還是比較好的)。
(我在我的一個Eclipse RCP項目里使用了這種模式,從Sql server 2000到Hsql,特別方便,看起來感覺也比較好)
歡迎大家拍轉,^_^
Job代表一個異步操作。
要執行的操作在run方法里。
schedule后,任務在平臺線程等待隊列中排隊,等待調度執行。
調用方式1:
調用方式2:
DatabaseMetaData?接口有超過150個方法,根據提供的信息可以分為以下幾類:
DatabaseMetaData?接口還有超過40個字段,這些字段用于DatabaseMetaData中各種方法的常量返回值。
這一章粗略介紹一下DatabaseMetaData接口,通過舉例子對元數據方法進行分類,同時介紹一些新的方法。詳細介紹請參考JDBC 4.0 類庫規范
JDBC中的ResultSetMetaData接口將在第15章“結果集”介紹。
// con是一個Connection對象 DatabaseMetaData dbmd = con.getMetadata(); int maxLen = dbmd.getMaxTableNameLength();
代碼示例 7-1 創建和使用DatabaseMetaData對象
判斷是否支持某個特性的方法如下:
查看特性支持級別的方法:
方法返回一個整型的限制數。0表示沒有限制或未知限制。
這些方法的完整定義見JDBC 4.0 類庫規范(javadoc)。
JDBC 4.0 類庫規范中有這些方法更新后的定義。
翻譯進度請參考http://www.pgsqldb.org/twiki/bin/view/PgSQL/JDBC4說明書
這一章描述了JDBC類庫實現在各個兼容級別要支持的特性。一個JDBC類庫實現包含了一個JDBC驅動和底層數據源。兼容性定義了在驅動層之上要實現的特性。
任何沒有提到的特性都是可選的。通常,如果底層數據源不支持,驅動不需要實現這個特性。
下列指導原則適合所有級別的兼容性:
與JDBC 1.0 類庫兼容的驅動應滿足以下條件:
JDBC 2.0類庫中不贊成使用的構造器和方法: java.sql.CallableStatement.getBigDecimal(int, int)
java.sql.Date(int, int, int)
java.sql.Date.getHours()
java.sql.Date.getMinutes()
java.sql.Date.getSeconds()
java.sql.Date.setHours(int)
java.sql.Date.setMinutes(int)
java.sql.Date.setSeconds(int)
java.sql.DriverManager.getLogStream()
java.sql.DriverManager.setLogStream(PrintStream?)
java.sql.PreparedStatement.setUnicodeStream(int, InputStream?, int)
java.sql.ResultSet.getBigDecimal(int, int)
java.sql.ResultSet.getBigDecimal(String, int)
java.sql.ResultSet.getUnicodeStream(int)
java.sql.ResultSet.getUnicodeStream(String)
java.sql.Time(int, int, int)
java.sql.Time.getDate()
java.sql.Time.getDay()
java.sql.Time.getMonth()
java.sql.Time.getYear()
java.sql.Time.setDate(int)
java.sql.Time.setMonth(int)
java.sql.Time.setYear(int)
java.sql.Timestamp(int, int, int, int, int, int, int)
以下類和接口組成了JDBC類庫
java.sql.AutoGeneratedKeys
java.sql.Array
java.sql.BaseQuery
java.sql.BatchUpdateException
java.sql.Blob
java.sql.CallableStatement
java.sql.ClientInfoException
java.sql.Column
java.sql.Clob
java.sql.Connection
java.sql.DataSet
java.sql.DataTruncation
java.sql.DatabaseMetaData
java.sql.Date
java.sql.Driver
java.sql.DriverManager
java.sql.DriverPropertyInfo
java.sql.NClob
java.sql.ParameterMetaData
java.sql.PreparedStatement
java.sql.Query
java.sql.QueryObjectFactory
java.sql.QueryObjectGenerator
java.sql.Ref
java.sql.ResultSet
java.sql.ResultSetMetaData
java.sql.RowId
java.sql.RowIdLifeTime
java.sql.Savepoint
java.sql.SQLData
java.sql.SQLDataException
java.sql.SQLException
java.sql.SQLInput
java.sql.SQLIntegrityConstraintViolationException
java.sql.SQLInvalidAuthorizationSpecException
java.sql.SQLNonTransientConnectionException
java.sql.SQLNonTransientException
java.sql.SQLOutput
java.sql.SQLPermission
java.sql.SQLSyntaxErrorException
java.sql.SQLTimeoutException
java.sql.SQLTransactionRollbackException
java.sql.SQLTransientConnectionException
java.sql.SQLTransientException
java.sql.SQLXML
java.sql.SQLWarning
java.sql.Statement
java.sql.Struct
java.sql.Table
java.sql.Time
java.sql.Timestamp
java.sql.Types
java.sql.Update
java.sql.Wrapper
下列類和接口是新增的或經過修改的。新的類和接口用粗體標出。
java.sql.AutoGeneratedKeys
java.sql.BaseQuery
java.sql.Blob
java.sql.CallableStatement
java.sql.ClientInfoException
java.sql.Clob
java.sql.Column
java.sql.Connection
java.sql.DatabaseMetaData
java.sql.NClob
java.sql.PreparedStatement
java.sql.Query
java.sql.QueryObjectFactory
java.sql.QueryObjectGenerator
java.sql.ResultSet
java.sql.RowId
java.sql.RowIdLifeTime
java.sql.SQLDataException
java.sql.SQLException
java.sql.SQLIntegrityConstraintViolationException
java.sql.SQLInvalidAuthorizationSpecException
java.sql.SQLNonTransientConnectionException
java.sql.SQLNonTransientException
java.sql.SQLSyntaxErrorException
java.sql.SQLTimeoutException
java.sql.SQLTransactionRollbackException
java.sql.SQLTransientConnectionException
java.sql.SQLTransientException
java.sql.SQLXML
java.sql.SQLWarning
java.sql.Statement
java.sql.Table
java.sql.Types
java.sql.Update
java.sql.Wrapper
javax.sql.CommonDataSource
javax.sql.StatementEvent
javax.sql.StatementEventListener
圖5-1顯示了java.sql包中關鍵類和接口之間的交互和關系,以及用于創建語句、設置參數、檢索結果的方法。
圖5-1 java.sql包中主要類和接口之間的關系
javax.sql.CommonDataSource
javax.sql.ConnectionEvent
javax.sql.ConnectionEventListener
javax.sql.ConnectionPoolDataSource
javax.sql.DataSource
javax.sql.PooledConnection
javax.sql.RowSet
javax.sql.RowSetEvent
javax.sql.RowSetInternal
javax.sql.RowSetListener
javax.sql.RowSetMetaData
javax.sql.RowSetReader
javax.sql.RowSetWriter
javax.sql.StatementEvent
javax.sql.StatementEventListener
javax.sql.XAConnection
javax.sql.XADataSource
圖5-2,圖5-3,圖5-4和圖5-5顯示了以下功能領域中關鍵類和接口之間的關系:DataSource對象,池化連接,分布式事務,行集。
圖5-2 javax.sql.DataSource和java.sql.Connection之間的關系
圖5-3 連接池化過程中涉及的關系
圖5-4 分布式事務支持中涉及的關系
圖5-5 行集涉及的關系
-- Main.Andyluo - 6 Oct 2005
問題虛擬背景:
A項目組要實現一個基于Sql Server的應用,但工作環境只安裝有MySql(公司對開源比較看好: )),而且客戶有可能會轉移到Oracle數據庫環境。要求應用具有數據庫移植能力和快速更換能力,使應用在工作環境調試成功后能迅速轉移到客戶的Sql Server環境,而且將來可以方便地轉向Oracle。
Andy提出的可用方案:
1、使用標準JDBC
2、使用抽象類定義數據訪問單元
3、定義具體數據源訪問單元繼承2中接口
代碼示例:
定義數據訪問單元抽象類,包含數據訪問邏輯
定義具體數據源訪問單元
在調用數據訪問層時,可以聲明一個DataManager的引用,然后在構造器中實例化為具體子類,如:
以后要遷移到另一個數據庫(有JDBC驅動),只需定義具體子類繼承DataManager(如HsqlDataManager),然后修改資源文件中的DataManager名稱(或者將new的類名改一下),不需要修改代碼。
這興許可以解釋另一個問題:不贊成使用存儲過程,而應將SQL語句嵌在代碼中(適用于Java;微軟注定.Net不會有平臺移植性,數據庫大都用Sql Server,所以寫存儲過程還是比較好的)。
(我在我的一個Eclipse RCP項目里使用了這種模式,從Sql server 2000到Hsql,特別方便,看起來感覺也比較好)
歡迎大家拍轉,^_^
Job代表一個異步操作。
要執行的操作寫在run方法里。
schedule后,任務在平臺線程等待隊列中排隊,等待調度執行。
調用方式1:
調用方式2:
DatabaseMetaData?接口有超過150個方法,根據提供的信息可以分為以下幾類:
DatabaseMetaData?接口還有超過40個字段,這些字段用于DatabaseMetaData中各種方法的常量返回值。
這一章粗略介紹一下DatabaseMetaData接口,通過舉例子對元數據方法進行分類,同時介紹一些新的方法。詳細介紹請參考JDBC 4.0 類庫規范
JDBC中的ResultSetMetaData接口將在第15章“結果集”介紹。
// con是一個Connection對象 DatabaseMetaData dbmd = con.getMetadata(); int maxLen = dbmd.getMaxTableNameLength();
代碼示例 7-1 創建和使用DatabaseMetaData對象
判斷是否支持某個特性的方法如下:
查看特性支持級別的方法:
方法返回一個整型的限制數。0表示沒有限制或未知限制。
這些方法的完整定義見JDBC 4.0 類庫規范(javadoc)。
JDBC 4.0 類庫規范中有這些方法更新后的定義。
翻譯進度請參考http://www.pgsqldb.org/twiki/bin/view/PgSQL/JDBC4說明書
這一章描述了JDBC類庫實現在各個兼容級別要支持的特性。一個JDBC類庫實現包含了一個JDBC驅動和底層數據源。兼容性定義了在驅動層之上要實現的特性。
任何沒有提到的特性都是可選的。通常,如果底層數據源不支持,驅動不需要實現這個特性。
下列指導原則適合所有級別的兼容性:
與JDBC 1.0 類庫兼容的驅動應滿足以下條件:
JDBC 2.0類庫中不贊成使用的構造器和方法: java.sql.CallableStatement.getBigDecimal(int, int)
java.sql.Date(int, int, int)
java.sql.Date.getHours()
java.sql.Date.getMinutes()
java.sql.Date.getSeconds()
java.sql.Date.setHours(int)
java.sql.Date.setMinutes(int)
java.sql.Date.setSeconds(int)
java.sql.DriverManager.getLogStream()
java.sql.DriverManager.setLogStream(PrintStream?)
java.sql.PreparedStatement.setUnicodeStream(int, InputStream?, int)
java.sql.ResultSet.getBigDecimal(int, int)
java.sql.ResultSet.getBigDecimal(String, int)
java.sql.ResultSet.getUnicodeStream(int)
java.sql.ResultSet.getUnicodeStream(String)
java.sql.Time(int, int, int)
java.sql.Time.getDate()
java.sql.Time.getDay()
java.sql.Time.getMonth()
java.sql.Time.getYear()
java.sql.Time.setDate(int)
java.sql.Time.setMonth(int)
java.sql.Time.setYear(int)
java.sql.Timestamp(int, int, int, int, int, int, int)
也可參考http://www.pgsqldb.org/twiki/bin/view/PgSQL/兼容性
以下類和接口組成了JDBC類庫
java.sql.AutoGeneratedKeys
java.sql.Array
java.sql.BaseQuery
java.sql.BatchUpdateException
java.sql.Blob
java.sql.CallableStatement
java.sql.ClientInfoException
java.sql.Column
java.sql.Clob
java.sql.Connection
java.sql.DataSet
java.sql.DataTruncation
java.sql.DatabaseMetaData
java.sql.Date
java.sql.Driver
java.sql.DriverManager
java.sql.DriverPropertyInfo
java.sql.NClob
java.sql.ParameterMetaData
java.sql.PreparedStatement
java.sql.Query
java.sql.QueryObjectFactory
java.sql.QueryObjectGenerator
java.sql.Ref
java.sql.ResultSet
java.sql.ResultSetMetaData
java.sql.RowId
java.sql.RowIdLifeTime
java.sql.Savepoint
java.sql.SQLData
java.sql.SQLDataException
java.sql.SQLException
java.sql.SQLInput
java.sql.SQLIntegrityConstraintViolationException
java.sql.SQLInvalidAuthorizationSpecException
java.sql.SQLNonTransientConnectionException
java.sql.SQLNonTransientException
java.sql.SQLOutput
java.sql.SQLPermission
java.sql.SQLSyntaxErrorException
java.sql.SQLTimeoutException
java.sql.SQLTransactionRollbackException
java.sql.SQLTransientConnectionException
java.sql.SQLTransientException
java.sql.SQLXML
java.sql.SQLWarning
java.sql.Statement
java.sql.Struct
java.sql.Table
java.sql.Time
java.sql.Timestamp
java.sql.Types
java.sql.Update
java.sql.Wrapper
下列類和接口是新增的或經過修改的。新的類和接口用粗體標出。
java.sql.AutoGeneratedKeys
java.sql.BaseQuery
java.sql.Blob
java.sql.CallableStatement
java.sql.ClientInfoException
java.sql.Clob
java.sql.Column
java.sql.Connection
java.sql.DatabaseMetaData
java.sql.NClob
java.sql.PreparedStatement
java.sql.Query
java.sql.QueryObjectFactory
java.sql.QueryObjectGenerator
java.sql.ResultSet
java.sql.RowId
java.sql.RowIdLifeTime
java.sql.SQLDataException
java.sql.SQLException
java.sql.SQLIntegrityConstraintViolationException
java.sql.SQLInvalidAuthorizationSpecException
java.sql.SQLNonTransientConnectionException
java.sql.SQLNonTransientException
java.sql.SQLSyntaxErrorException
java.sql.SQLTimeoutException
java.sql.SQLTransactionRollbackException
java.sql.SQLTransientConnectionException
java.sql.SQLTransientException
java.sql.SQLXML
java.sql.SQLWarning
java.sql.Statement
java.sql.Table
java.sql.Types
java.sql.Update
java.sql.Wrapper
javax.sql.CommonDataSource
javax.sql.StatementEvent
javax.sql.StatementEventListener
圖5-1顯示了java.sql包中關鍵類和接口之間的交互和關系,以及用于創建語句、設置參數、檢索結果的方法。
圖5-1 java.sql包中主要類和接口之間的關系
javax.sql.CommonDataSource
javax.sql.ConnectionEvent
javax.sql.ConnectionEventListener
javax.sql.ConnectionPoolDataSource
javax.sql.DataSource
javax.sql.PooledConnection
javax.sql.RowSet
javax.sql.RowSetEvent
javax.sql.RowSetInternal
javax.sql.RowSetListener
javax.sql.RowSetMetaData
javax.sql.RowSetReader
javax.sql.RowSetWriter
javax.sql.StatementEvent
javax.sql.StatementEventListener
javax.sql.XAConnection
javax.sql.XADataSource
圖5-2,圖5-3,圖5-4和圖5-5顯示了以下功能領域中關鍵類和接口之間的關系:DataSource對象,池化連接,分布式事務,行集。
圖5-2 javax.sql.DataSource和java.sql.Connection之間的關系
圖5-3 連接池化過程中涉及的關系
圖5-4 分布式事務支持中涉及的關系
圖5-5 行集涉及的關系
-- Main.Andyluo - 6 Oct 2005
也可參照http://www.pgsqldb.org/twiki/bin/view/PgSQL/類和接口
==========================================================
概述
JDBC類庫使得Java程序可以訪問多個數據源,但在大多數情況下,這個數據源是關系數據庫,并且通過SQL訪問。然而,實現JDBC技術的驅動也可以基于其它的數據源,包括遺留文件系統和面向對象的系統。JDBC類庫的一個主要目的就是提供一個應用程序訪問多種數據源的標準接口。
這一章介紹JDBC類庫的一些關鍵概念,并描述JDBC應用的兩個通用環境及其中的功能實現。兩層和三層模型都是能被實現在多個物理配置上的邏輯模型。
=================================================
4.1 創建連接
JDBC類庫中的Connection接口代表了底層數據源的一個連接。
在典型場景中,JDBC應用程序使用兩種機制連接到數據源:
1.DriverManager --- 這個類在JDBC 1.0中引入,它使用硬編碼的URL來加載驅動。
2.DataSource --- 這個接口在JDBC 2.0可選包中引入。它優于DriverManager方式,因為它隱藏了數據源的詳細信息。我們通過設置DataSource的屬性來標明它代表的數據源。當getConnection方法被調用時,DataSource對象會返回一個對應的連接。我們可以通過改變DataSource的屬性來使它指向另一個數據源,而不是改變程序代碼。而且,即使DataSource的實現改變了,使用它的應用程序代碼也不需要改變。
JDBC類庫定義了兩個DataSource的擴展來支持企業級應用,如下:
1.ConnectionPoolDataSource --- 支持物理連接的緩存和重用,這樣可以提高應用的性能和可伸縮性。
2.XADataSource --- 提供可以使用在分布式事務中的連接。
=========================================================
4.2 執行SQL語句和操縱結果
連接建立后,我們可以使用JDBC類庫對目標數據源進行查詢和更新。JDBC類庫提供了對大多數SQL2003通用特性的支持。由于各個廠商可能要支持不同的特性,JDBC類庫提供了一個DatabaseMetadata接口。應用可以通過這個接口了解數據源是否支持某個特性。JDBC類庫也定義了轉義語義來支持特定廠商非標準的特性。轉義語義使得我們可以訪問與本地程序相同的SQL特性集,同時保持應用的可移植性。
應用通過使用Connection接口來設置事務屬性和創建Statement, PreparedStatement和CallableStatement. 這些statement被用來執行SQL語句和檢索結果。ResultSet接口封裝了SQL查詢的結果。語句也可以批處理,這樣應用可以通過一次單元執行提交對數據源的多次更新。
RowSet接口擴展了ResultSet接口。它提供了一個比標準結果集功能更多的表數據容器。RowSet對象是Java Beans組件,它可以在中斷數據庫連接的情況下操縱數據。例如,一個RowSet實現可以被序列化從而傳送到網絡上,這對于吞吐量小的客戶端尤為有用,因為這可以省去加載JDBC驅動和建立JDBC連接的開銷。RowSet還可以使用定制的閱讀器(Reader)來訪問表格數據(不僅僅是關系數據庫的數據)。甚者,RowSet對象可以在中斷數據庫連接的情況下更新數據,并在連接正常時通過一個定制的書寫器(Writer)將更新寫入數據源。
4.2.1 對SQL高級數據類型的支持
JDBC類庫定義了SQL數據類型到JDBC數據類型的標準映射。映射也包含了對SQL2003高級數據類型如BLOB,CLOB,ARRAY,REF,STRUCT和DISTINCT的支持。JDBC驅動也可以實現多個用戶自定義類型(UDTs,user-defined types)的映射,在這里,每個UDT映射到Java中的一個類。
JDBC類庫也提供對外部數據的支持,例如數據源外部的一個文件。
========================================
4.3 兩層模型
兩層模型將功能分配到客戶端和服務器端,如圖4-1.
FIGURE 4-1 兩層模型
客戶端包含了應用和一個或多個JDBC驅動,這些應用負責下列內容:
* 表示邏輯
* 業務邏輯
* 對多語句事務(multiple-statement transactions)或分布式事務的管理
* 資源管理
在這個模型中,應用直接跟JDBC驅動打交道,包括建立和管理物理連接,以及處理底層數據源的相關細節。應用可以通過對數據源實現的了解來使用它的非標準特性或者提升性能。
模型的缺點:
* 將表示邏輯、業務邏輯和基礎設施、系統級別的功能混淆在一起,不利于維護。
* 由于被綁定到特定的數據庫,應用很難被移植。需要連接到多個數據庫的應用要注意各個廠商實現的區別。
* 缺少可伸縮性。典型地,應用將從始至終占有一個或多個物理連接,缺少對并發應用的支持。在這個模型中,性能、可伸縮性和可靠性問題都是由JDBC驅動和底層數據源處理的。如果應用要跟多個驅動打交道,它需要注意每個驅動/數據源對是怎么處理這些問題的。
======================================================
4.4 三層模型
三層模型引入了中間層服務器來管理業務邏輯和基礎結構,如圖4-2.
FIGURE 4-2 三層模型
這個架構為企業級應用提供了更好的性能、可伸縮性和可靠性。功能劃分如下:
1.客戶端 --- 只負責表示邏輯,處理人機交互。Java應用程序、網頁瀏覽器和PDA等都是典型的客戶端。客戶端與中間層應用交互,它不需要了解底層的基礎結構和數據源實現。
2.中間層服務器 --- 中間層包含:
* 一些應用程序。這些應用負責跟客戶端打交道和實現業務邏輯。如果應用包含與數據源的交互,它應該使用高層抽象,例如DataSource對象和邏輯連接,而不是底層的驅動程序類庫。
* 一個應用服務器。提供支持大部分應用的基礎結構。這可能包含管理和池化物理連接、管理事務和掩蓋不同JDBC驅動的細節。最后一點使得應用更容易被移植。應用服務器可以使用J2EE服務器。它應該直接和JDBC驅動交互和提供高層應用使用的功能抽象。
* 一個或多個JDBC驅動。提供與底層數據源的連接,每個驅動使用底層數據源支持的特性來實現標準JDBC類庫。驅動層需要掩蓋SQL2003標準和底層數據源語言的不同。如果數據源不是一個關系型數據庫管理系統(DBMS),那么驅動要實現應用服務器使用的關系層。
3.底層數據源 --- 存放數據的層。包含關系型數據庫管理系統(relational DBMS),遺留文件系統,面向對象的DBMS,數據倉庫,報表或者其他包裝和表示數據的方式,只要有對應的支持JDBC類庫的驅動。
===================================================
4.5 J2EE平臺中的JDBC
J2EE組件,例如JSP,Servlets和EJB,經常需要利用JDBC類庫訪問關系型數據。當在J2EE組件里使用JDBC類庫時,容器可能幫你管理事務和數據源(譯者注:Container Managed Persistence,容器管理持久性)。這樣,J2EE組件開發者就不直接使用JDBC類庫的事務和數據源管理功能。詳情請見J2EE平臺規范。
=====================================================
概述
JDBC類庫使得Java程序可以訪問多個數據源,但在大多數情況下,這個數據源是關系數據庫,并且通過SQL訪問。然而,實現JDBC技術的驅動也可以基于其它的數據源,包括遺留文件系統和面向對象的系統。JDBC類庫的一個主要目的就是提供一個應用程序訪問多種數據源的標準接口。
這一章介紹JDBC類庫的一些關鍵概念,并描述JDBC應用的兩個通用環境及其中的功能實現。兩層和三層模型都是能被實現在多個物理配置上的邏輯模型。
=====================================================
4.1 創建連接
JDBC類庫中的Connection接口代表了底層數據源的一個連接。
在典型場景中,JDBC應用程序使用兩種機制連接到數據源:
1.DriverManager --- 這個類在JDBC 1.0中引入,它使用硬編碼的URL來加載驅動。
2.DataSource --- 這個接口在JDBC 2.0可選包中引入。它優于DriverManager方式,因為它隱藏了數據源的詳細信息。我們通過設置DataSource的屬性來標明它代表的數據源。當getConnection方法被調用時,DataSource對象會返回一個對應的連接。我們可以通過改變DataSource的屬性來使它指向另一個數據源,而不是改變程序代碼。而且,即使DataSource的實現改變了,使用它的應用程序代碼也不需要改變。
JDBC類庫定義了兩個DataSource的擴展來支持企業級應用,如下:
1.ConnectionPoolDataSource --- 支持物理連接的緩存和重用,這樣可以提高應用的性能和可伸縮性。
2.XADataSource --- 提供可以使用在分布式事務中的連接。
======================================================
4.2 執行SQL語句和操縱結果
連接建立后,我們可以使用JDBC類庫對目標數據源進行查詢和更新。JDBC類庫提供了對大多數SQL2003通用特性的支持。由于各個廠商可能要支持不同的特性,JDBC類庫提供了一個DatabaseMetadata接口。應用可以通過這個接口了解數據源是否支持某個特性。JDBC類庫也定義了轉義語義來支持特定廠商非標準的特性。轉義語義使得我們可以訪問與本地程序相同的SQL特性集,同時保持應用的可移植性。
應用通過使用Connection接口來設置事務屬性和創建Statement,PreparedStatement和CallableStatement. 這些statement被用來執行SQL語句和檢索結果。ResultSet接口封裝了SQL查詢的結果。語句也可以批處理,這樣應用可以通過一次單元執行提交對數據源的多次更新。
RowSet接口擴展了ResultSet接口。它提供了一個比標準結果集功能更多的表數據容器。RowSet對象是Java Beans組件,它可以在中斷數據庫連接的情況下操縱數據。例如,一個RowSet實現可以被序列化從而傳送到網絡上,這對于吞吐量小的客戶端尤為有用,因為這可以省去加載JDBC驅動和建立JDBC連接的開銷。RowSet還可以使用定制的閱讀器(Reader)來訪問表格數據(不僅僅是關系數據庫的數據)。甚者,RowSet對象可以在中斷數據庫連接的情況下更新數據,并在連接正常時通過一個定制的書寫器(Writer)將更新寫入數據源。
4.2.1 對SQL高級數據類型的支持
JDBC類庫定義了SQL數據類型到JDBC數據類型的標準映射。映射也包含了對SQL2003高級數據類型如BLOB,CLOB,ARRAY,REF,STRUCT和DISTINCT的支持。JDBC驅動也可以實現多個用戶自定義類型(UDTs,user-defined types)的映射,在這里,每個UDT映射到Java中的一個類。
JDBC類庫也提供對外部數據的支持,例如數據源外部的一個文件。
========================================
4.3 兩層模型
兩層模型將功能分配到客戶端和服務器端,如圖4-1.
FIGURE 4-1 兩層模型
客戶端包含了應用和一個或多個JDBC驅動,這些應用負責下列內容:
* 表示邏輯
* 業務邏輯
* 對多語句事務(multiple-statement transactions)或分布式事務的管理
* 資源管理
在這個模型中,應用直接跟JDBC驅動打交道,包括建立和管理物理連接,以及處理底層數據源的相關細節。應用可以通過對數據源實現的了解來使用它的非標準特性或者提升性能。
模型的缺點:
* 將表示邏輯、業務邏輯和基礎設施、系統級別的功能混淆在一起,不利于維護。
* 由于被綁定到特定的數據庫,應用很難被移植。需要連接到多個數據庫的應用要注意各個廠商實現的區別。
* 缺少可伸縮性。典型地,應用將從始至終占有一個或多個物理連接,缺少對并發應用的支持。在這個模型中,性能、可伸縮性和可靠性問題都是由JDBC驅動和底層數據源處理的。如果應用要跟多個驅動打交道,它需要注意每個驅動/數據源對是怎么處理這些問題的。
======================================================
4.4 三層模型
三層模型引入了中間層服務器來管理業務邏輯和基礎結構,如圖4-2.
FIGURE 4-2 三層模型
這個架構為企業級應用提供了更好的性能、可伸縮性和可靠性。功能劃分如下:
1.客戶端 --- 只負責表示邏輯,處理人機交互。Java應用程序、網頁瀏覽器和PDA等都是典型的客戶端。客戶端與中間層應用交互,它不需要了解底層的基礎結構和數據源實現。
2.中間層服務器 --- 中間層包含:
* 一些應用程序。這些應用負責跟客戶端打交道和實現業務邏輯。如果應用包含與數據源的交互,它應該使用高層抽象,例如DataSource對象和邏輯連接,而不是底層的驅動程序類庫。
* 一個應用服務器。提供支持大部分應用的基礎結構。這可能包含管理和池化物理連接、管理事務和掩蓋不同JDBC驅動的細節。最后一點使得應用更容易被移植。應用服務器可以使用J2EE服務器。它應該直接和JDBC驅動交互和提供高層應用使用的功能抽象。
* 一個或多個JDBC驅動。提供與底層數據源的連接,每個驅動使用底層數據源支持的特性來實現標準JDBC類庫。驅動層需要掩蓋SQL2003標準和底層數據源語言的不同。如果數據源不是一個關系型數據庫管理系統(DBMS),那么驅動要實現應用服務器使用的關系層。
3.底層數據源 --- 存放數據的層。包含關系型數據庫管理系統(relational DBMS),遺留文件系統,面向對象的DBMS,數據倉庫,報表或者其他包裝和表示數據的方式,只要有對應的支持JDBC類庫的驅動。
===================================================
4.5 J2EE平臺中的JDBC
J2EE組件,例如JSP,Servlets和EJB,經常需要利用JDBC類庫訪問關系型數據。當在J2EE組件里使用JDBC類庫時,容器可能幫你管理事務和數據源(譯者注:Container Managed Persistence,容器管理持久性)。這樣,J2EE組件開發者就不直接使用JDBC類庫的事務和數據源管理功能。詳情請見J2EE平臺規范。
其它章節的翻譯參見:
http://www.pgsqldb.org/twiki/bin/view/PgSQL/JDBC4%E8%AF%B4%E6%98%8E%E4%B9%A6
=================================================================
序言
這個文檔鞏固了下面幾個規范的內容:
“JDBC: Java的SQL類庫”
“JDBC 2.1 類庫”
“JDBC 2.0 標準擴展類庫”
“JDBC 3.0 規范”
文檔介紹了JDBC 4.0 類庫的新特征和一些增強的特征。文檔根據不同特征劃分章節,這樣可以更方便了解JDBC 4.0和3.0的不同之處。
讀者如果想了解JDBC類庫的詳細信息,可以參考JDBC的類庫文檔(Javadoc),該文檔可以由以下鏈接獲得:
http://java.sun.com/products/jdbc
==========================================================================
介紹
1.1 JDBC類庫
JDBC類庫提供了通過Java語言訪問關系數據庫的能力。Java程序通過JDBC可以執行SQL語句,對獲取的數據進行處理,并將變化了的數據存回數據庫。在分布式異構環境中,我們還可以通過JDBC操縱多個數據源。
JDBC類庫基于X/Open SQL通用語言接口(CLI),ODBC也基于此。JDBC提供了一個使用方便的映射方案:從Java語言到X/Open 通用語言接口和SQL標準的抽象實體及概念的映射。
自1997年的產生至今,JDBC類庫已被廣泛的接受和實現。類庫的靈活性使得它可以有很多個具體實現。
1.2 平臺
JDBC類庫是Java平臺的一部分。4.0版分為兩個包:java.sql 和 javax.sql。這兩個包都包含在JSE(Java桌面版)和JEE(Java企業版)中。
1.3 適合讀者
該文檔主要面向下列產品的開發者:
1. JDBC驅動程序
2. 基于數據庫驅動提供三層架構服務的應用服務器
3. 使用JDBC類庫來提供服務的工具
該文檔想達到以下目的:
1.對使用JDBC類庫的開發者的一個介紹
2.作為開發基于JDBC的類庫的起始點
===============================================================
目標
2.1 歷史
2.2 JDBC 4.0 之目標
---1.與JEE和JSE平臺相處融洽
---2.與SQL:2003一致
---3.鞏固前述四個規范
---4.提供中立于廠商的通用功能
---5.主要只針對SQL類型的數據源
---6.提供高層類庫和工具的基礎設施
---7.保持簡單
---8.加強可靠性、可用性和可伸縮性
---9.保持向后兼容性
---10.與JDBC行集(RowSet)緊密聯系
---11.與連接器架構(Connectors)兼容
---12.清晰描述JDBC需求
==================================================================
新特性概覽
3.1 變更概覽
JDBC 4.0 類庫在以下領域注入了變化和新的元素:
1.自動加載java.sql.Driver
DriverManager.getConnection方法被修改以利用JSE的服務提供者機制來自動加載JDBC驅動。這樣就不需要調用Class.forName方法了。
2.類庫使用更容易
添加了標準JDBC注釋。支持數據集(DataSet),使Java應用調用SQL數據源更加方便。
3.ROWID數據類型
添加了java.sql.RowID數據類型,使得JDBC程序可以訪問SQL ROWID。
4.支持本地字符集轉換(National Character Set Conversion)
添加了一些JDBC類型:NCHAR, NVARCHAR, LONGVARCHAR, NCLOB。對應的方法setNString, setNCharacterStream, setNClob也被添加到PreparedStatement接口中。
5.增強了對BLOB和CLOB的支持
Connection接口添加了生產BLOB,CLOB和NCLOB對象的方法。PreparedStatement接口添加了通過InputStream插入BLOB的方法和使用Reader插入CLOB,NCLOB的方法。Blob, Clob和NClob現在可以通過free方法釋放資源。
6.SQL/XML和XML支持
SQL2003引入了用SQL表達XML數據的概念。一些類庫被添加進來以支持應用對這些數據的訪問。
7.包裝器(Wrapper)模式
添加了解包JDBC實現的能力,使開發者可以利用在廠商實現中提供的非標準JDBC方法。
8.加強的SQLException
添加對JSE鏈式異常的支持。SQLException現在支持Iterable接口,所以我們可以在for-each循環里讀取SQLExceptions。新添加了兩類SQL異常:SQLTransientException和SQLNonTransientException。每個類都提供映射到普通SQLState類型值(譯者注:SQLState?)的子類。
9.連接管理
Connection和Statement接口得到了增強,以利于對連接狀態的跟蹤,并增加在池環境中管理Statement對象的靈活性。
10.JDBC類庫的變化
下面的JDBC接口被修改:
---10.1 Connection
添加了下列方法:createBlob, createClob, createNClob, createQueryObject, isValid, createXML, getClientInfo, setClientInfo。
---10.2 CallableStatement
添加了下列方法:getRowId, setRowId, getNClob, setNString, setNCharacterStream, setNClob, getSQLXML, setSQLXML。重載了setClob和setBlob方法。
---10.3 DatabaseMetaData
添加了下列方法:getRowIdLifetime, autoCommitFailureClosesAllResultSets, providesQueryObjectGenerator, getClientInfoProperties, supportsStoredFunctionsUsingCallSyntax. 重載了getSchemas方法。
---10.4 PreparedStatement
添加了下列方法:setRowId, setNString, setNCharacterStream, setSQLXML, isPoolable, setPoolable, setNClob。重載了setClob和setBlob方法。
---10.5 ResultSet
添加了下列方法:getHoldability, getRowId, updateRowID, getNClob, isClosed, updateNString, getSQLXML, updateSQLXML, updateNClob。
---10.6 Statement
添加了isClosed和getResultSetHoldability方法。
---10.7 DataSource
添加了createQueryObject方法。
---10.8 PooledConnection
添加了addStatementEventListener和removeStatementEventListener方法。
====================================================================
概覽
JDBC類庫使得Java程序可以訪問多個數據源,但在大多數情況下,這個數據源是關系數據庫,并且通過SQL訪問。然而,實現JDBC技術的驅動也可以基于其它的數據源,包括遺留文件系統和面向對象的系統。
JDBC類庫的主要目的就是提供應用程序訪問多種數據源的標準接口。
這一章介紹JDBC類庫的一些關鍵概念,并描述JDBC應用的兩個通用環境及其中的功能實現。
4.1 創建連接
JDBC類庫中的Connection接口代表了底層數據源的一個連接。
在典型場景中,JDBC應用程序使用兩種機制連接到數據源:
1.DriverManager --- 這個類在JDBC 1.0中引入,它使用硬編碼的URL來加載驅動。
2.DataSource --- 這個接口在JDBC 2.0可選包中引入。它優于DriverManager方式,因為它隱藏了數據源的詳細信息。我們通過設置DataSource的屬性來標明它代表的數據源。當getConnection方法被調用時,DataSource對象會返回一個對應的連接。我們可以通過改變DataSource的屬性來使它指向另一個數據源,而不是改變程序代碼。而且,如果DataSource的實現改變了,使用它的應用程序代碼不需要改變。
JDBC類庫也定義了兩個DataSource的擴展,用來支持企業級應用,如下:
1.ConnectionPoolDataSource --- 支持物理連接的緩存和重用,這樣可以提高應用的性能和可伸縮性。
2.XADataSource --- 提供可以使用在分布式事務中的連接。