1、JDBC3.0規范中數據庫連接池框架
JDBC3.0規范中通過提供了一個支持數據庫連接池的框架,這個框架僅僅規定了如何支持連接池的實現,而連接池的具體實現JDBC 3.0規范并沒有做相關的規定。通過這個框架可以讓不同角色的開發人員共同實現數據庫連接池。
通過JDBC3.0規范可以知道具體數據庫連接池的實現可以分為JDBC Driver級和Application Server級。在JDBC Driver級的實現中任何相關的工作均由特定數據庫廠商的JDBC Drvier的開發人員來具體實現,即JDBC Driver既需要提供對數據庫連接池的支持同時也必須對數據庫連接池進行具體實現。而在Application Server級中數據庫連接池的實現中特定數據庫廠商的JDBC Driver開發人員和Application Server開發人員來共同實現數據庫連接池的實現(但是現在大多數Application Server廠商實現的連接池的機制和規范中提到有差異),其中特定數據庫廠商的JDBC Driver提供數據庫連接池的支持而特定的Application Server廠商提供數據庫連接池的具體實現。
JDBC3.0規范規定了如下的類和接口來支持數據庫連接池的實現。
javax.sql.ConnectionEvent
javax.sql.ConnectionPoolDataSource
javax.sql.PooledConnection
javax.sql.ConnectionEventListener |
其中除javax.sql.ConnectionEvent是類,其它的均為接口。

圖1 JDBC3.0連接池框架的關系圖
通過此圖可以大概的了解相關接口在一個典型的三層環境中應用程序的位置。
2、檢索自動產生的關鍵字
為了解決對獲取自動產生的或自動增加的關鍵字的值的需求,JDBC 3.0 API 現在將獲取這種值變得很輕松。要確定任何所產生的關鍵字的值,只要簡單地在語句的 execute() 方法中指定一個可選的標記,表示您有興趣獲取產生的值。您感興趣的程度可以是 Statement.RETURN_GENERATED_KEYS,也可以是 Statement.NO_GENERATED_KEYS。在執行這條語句后,所產生的關鍵字的值就會通過從 Statement 的實例方法 getGeneratedKeys() 來檢索 ResultSet 而獲得,ResultSet 包含了每個所產生的關鍵字的列,下面的示例創建一個新的作者并返回對應的自動產生的關鍵字。
……
Statement stmt = conn.createStatement();
// Obtain the generated key that results from the query.
stmt.executeUpdate("INSERT INTO authors " +
"(first_name, last_name) " +
"VALUES (‘Ghq’, ‘Wxl’)",
Statement.RETURN_GENERATED_KEYS);
ResultSet rs = stmt.getGeneratedKeys();
if ( rs.next() ) {
// Retrieve the auto generated key(s).
int key = rs.getInt();
}
…… |
3、返回多重結果
JDBC 2 規范的一個局限是,在任意時刻,返回多重結果的語句只能打開一個 ResultSet。作為 JDBC 3.0 規范中改變的一個部分,規范將允許 Statement 接口支持多重打開的 ResultSets。然而,重要的是 execute() 方法仍然會關閉任何以前 execute() 調用中打開的 ResultSet。所以,要支持多重打開的結果,Statement 接口就要加上一個重載的 getMoreResults() 方法。新式的方法會做一個整數標記,在 getResultSet() 方法被調用時指定前一次打開的 ResultSet 的行為。接口將按如下所示定義標記:
CLOSE_ALL_RESULTS:當調用 getMoreResults() 時,所有以前打開的 ResultSet 對象都將被關閉。
CLOSE_CURRENT_RESULT:當調用 getMoreResults() 時,當前的 ResultSet 對象將被關閉。
KEEP_CURRENT_RESULT:當調用 getMoreResults() 時,當前的 ResultSet 對象將不會被關閉。
下面展示的是一個處理多重打開結果的示例。
……
String procCall;
// Set the value of procCall to call a stored procedure.
// …
CallableStatement cstmt = connection.prepareCall(procCall);
int retval = cstmt.execute();
if (retval == false) {
// The statement returned an update count, so handle it.
// …
} else { // ResultSet
ResultSet rs1 = cstmt.getResultSet();
// …
retval = cstmt.getMoreResults(Statement.KEEP_CURRENT_RESULT);
if (retval == true) {
ResultSet rs2 = cstmt.getResultSet();
// Both ResultSets are open and ready for use.
rs2.next();
rs1.next();
// …
}
}
…… |
4、在事務中使用 Savepoint
也許在 JDBC 3.0 中最令人興奮的附加特點就是 Savepoint 了。JDBC 2 中的事務支持讓開發人員可以控制對數據的并發訪問,從而保證持續數據總是保持一致的狀態。可惜的是,有時候需要的是對事務多一點的控制,而不是在當前的事務中簡單地對每一個改變進行回滾。在JDBC 3.0 下,可以通過 Savepoint 獲得這種控制。Savepoint 接口允許您將事務分割為各個邏輯斷點,以控制有多少事務需要回滾。下圖3 將說明如何在事務中運用 Savepoint。

圖2 Savepoint 的直觀表示
你或許不是經常需要使用 Savepoint。然而,在一種普遍的情況下 Savepoint 會發揮作用,那就是您需要作一系列的改變,但是在知道所有的結果之前不能確定應該保留這些改變的哪一部分。下面的代碼示例說明了如何使用 Savepoint 接口。
......
conn.setAutoCommit(false);
// Set a conservative transaction isolation level.
conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
Statement stmt = conn.createStatement();
int rows = stmt.executeUpdate( "INSERT INTO authors " +
" (first_name, last_name) VALUES " +
" ('Ghq', 'Wxl')");
// Set a named savepoint.
Savepoint svpt = conn.setSavepoint("NewAuthor");
// …
rows = stmt.executeUpdate( "UPDATE authors set type = 'fiction' " +
"WHERE last_name = 'Wxl'");
// …
conn.rollback(svpt);
// …
// The author has been added, but not updated.
conn.commit();
...... |
5、其他的特性
1)元數據 API
元數據 API 已經得到更新,DatabaseMetaData 接口現在可以檢索 SQL 類型的層次結構,一種新的 ParameterMetaData 接口可以描述 PreparedStatement 對象中參數的類型和屬性。
2)CallableStatements 中已命名的參數
在 JDBC 3.0 之前,設置一個存儲過程中的一個參數要指定它的索引值,而不是它的名稱。 CallableStatement 接口已經被更新了,現在您可以用名稱來指定參數。
3)數據類型的改變
JDBC 所支持的數據類型作了幾個改變,其中之一是增加了兩種新的數據類型。
為了便于修改 CLOB(Character Large OBject,字符型巨對象)、BLOB(Binary Large OBject,二進制巨對象)和 REF(SQL 結構)類型的值,同名的數據類型接口都被更新了。接下來的是,因為我們現在能夠更新這些數據類型的值,所以 ResultSet 接口也被修改了,以支持對這些數據類型的列的更新,也包括對 ARRAY 類型的更新。增加的兩種新的數據類型是 java.sql.Types.DATALINK 和 java.sql.Types.BOOLEAN。新增的數據類型指的是同名的 SQL 類型。DATALINK 提供對外部資源的訪問或 URL,而 BOOLEAN 類型在邏輯上和 BIT 類型是等同的,只是增加了在語義上的含義。DATALINK 列值是通過使用新的 getURL() 方法從 ResultSet 的一個實例中檢索到的,而 BOOLEAN 類型是通過使用 getBoolean() 來檢索的。
|