9.2? JDBC API 2.0 簡介
9.2.1? 新的記錄集接口(ResultSet接口)
1 新定義了若干個常數
這些常數用于指定ResultSet的類型 游標移動的方向等性質 如下所示?
public static final int FETCH_FORWARD;
public static final int FETCH_REVERSE;
public static final int FETCH_UNKNOWN;
public static final int TYPE_FORWARD_ONLY;
public static final int TYPE_SCROLL_INSENSITIVE;
public static final int TYPE_SCROLL_SENSITIVE;
public static final int CONCUR_READ_ONLY;
public static final int CONCUR_UPDATABLE;
FETCH_FORWORD 該常數的作用是指定處理記錄集中行的順序是由前到后 即從第一行開始處理 一直到最后一行?
FETCH_REVERSE 該常數的作用是指定處理記錄集中行的順序是由后到前 即從后一行開始處理 一直到第一行?
FETCH_UNKNOWN 該常數的作用是不指定處理記錄集中行的順序 由 JDBC 驅動程序和數據庫系統決定?
TYPE_FORWARD_ONLY 該常數的作用是指定數據庫游標的移動方向是向前 不允許向后移動 即只能使用ResultSet接口的next()方法 而不能使用 previous()方法 否則會產生錯誤?
TYPE_SCROLL_INSENSITIVE 該常數的作用是指定數據庫游標可以在記錄集中前后
移動 并且當前數據庫用戶獲取的記錄集對其他用戶的操作不敏感 就是說 當前用戶正
在瀏覽記錄集中的數據 與此同時 其他用戶更新了數據庫中的數據 但是當前用戶所獲
取的記錄集中的數據不會受到任何影響?
TYPE_SCROLL_SENSITIVE 該常數的作用是指定數據庫游標可以在記錄集中前后移動 并且當前數據庫用戶獲取的記錄集對其他用戶的操作敏感 就是說 當前用戶正在瀏覽記錄集 但是其它用戶的操作使數據庫中的數據發生了變化 當前用戶所獲取的記錄集中的數據也會同步發生變化 這樣有可能會導致非常嚴重的錯誤產生 建議慎重使用該常數?
CONCUR_READ_ONLY 該常數的作用是指定當前記錄集的協作方式(concurrency mode)為只讀 一旦使用了這個常數 那么用戶就不可以更新記錄集中的數據? CONCUR_UPDATABLE 該常數的作用是指定當前記錄集的協作方式(concurrency mode)為可以更新 一旦使用了這個常數 那么用戶就可以使用 updateXXX()等方法更新記錄集中的數據?
2 ResultSet接口提供了一整套的定位方法
這些可以在記錄集中定位到任意一行 具體有?
public boolean absolute(int? row);? 該方法的作用是將記錄集中的某一行設定為當前行 亦即將數據庫游標移動到指定的行 參數 row指定了目標行的行號 這是絕對的行號由記錄集的第一行開始計算 不是相對的行號?
public boolean relative(int? rows);? 該方法的作用也是將記錄集中的某一行設定為當前行 但是它的參數 rows表示目標行相對于當前行的行號 例如當前行是第3行 現在需要移動到第5行去 既可以使用absolute()方法 也可以使用 relative()方法 代碼如下?
例?
rs.absolute(5);
或者
rs.relative(2);
其中rs代表ResultSet接口的實例對象?
又如當前行是第5行 需要移動到第 3行去 代碼如下?
例?
rs.absolute(3);
或者
rs.relative(-2);
其中rs代表ResultSet接口的實例對象?
讀者需要注意的問題是 傳遞給 relative()方法的參數 如果是正數 那么數據庫游標向前移動 如果是負數 那么數據庫游標向后移動?
注意 在本章中所說的數據庫游標向前移動是指向行號增大的方向移動 向后移動是指向行號減少的方向移動?
public boolean first();? 該方法的作用是將當前行定位到數據庫記錄集的第一行?
public boolean last();? 該方法的作用剛好和 first()方法相反 是將當前行定位到數據庫記錄集的最后一行?
public boolean isFirst();? 該方法的作用是檢查當前行是否記錄集的第一行 如果是返回true 否則 返回false?
public boolean isLast();?? 該方法的作用是檢查當前行是否記錄集的最后一行 如果是 返回true 否則 返回false?
public void afterLast();? 該方法的作用是將數據庫游標移到記錄集的最后 位于記錄集最后一行的后面 如果該記錄集不包含任何的行 該方法不產生作用?
public void beforeFirst();?? 該方法的作用是將數據庫游標移到記錄集的最前面 位于記錄集第一行的前面 如果記錄集不包含任何的行 該方法不產生作用?
public boolean isAfterLast();? 該方法檢查數據庫游標是否處于記錄集的最后面 如果是 返回true 否則 返回false?
public boolean isBeforeFirst();? 該方法檢查數據庫游標是否處于記錄集的最前面 如果是 返回true 否則 返回false?
public boolean next();? 該方法的作用是將數據庫游標向前移動一位 使得下一行成為當前行 當剛剛打開記錄集對象時 數據庫游標的位置在記錄集的最前面 第一次使用 next()方法 將會使數據庫游標定位到記錄集的第一行 第二次使用 next()方法 將會使數據庫游標定位到記錄集的第二行 以此類推?
注意 如果在當前行打開了一個輸入流(Input Stream) 那么再次使用 next()方法時將會自動關閉該輸入流?
public boolean previous();? 該方法的作用是將數據庫游標向后移動一位 使得上一行成為當前行?
3 ResultSet接口添加了對行操作的支持
使用JDBC API 2.0 不僅可以任意將數據庫游標定位到記錄集中的特定行 而且還可以使用ResultSet接口新定義的一套方法更新當前行的數據 在以前 如果Java程序員希望更新記錄集中某行的數據 必須發送 SQL 語句給數據庫 程序員需要在 Java 代碼中嵌入冗長的SQL語句 用以執行 UPDATE DELETE INSERT 等數據庫操作 但是 當JDBC API 2.0 出現時 一切就都改變了 程序員已經可以部分拋開 SQL語言 享受Java編程的樂趣了 ResultSet接口中新添加的部分方法如下所示?
public boolean rowDeleted();? 如果當前記錄集的某行被刪除了 那么記錄集中將會留
出一個空位 調用rowDeleted()方法 如果探測到空位的存在 那么就返回 true 如果沒有探測到空位的存在 就返回false值?
public boolean rowInserted();?? 如果當前記錄集中插入了一個新行 該方法將返回true 否則返回false?
public boolean rowUpdated();?? 如果當前記錄集的當前行的數據被更新 該方法返回true 否則返回false?
public void insertRow();?? 該方法將執行插入一個新行到當前記錄集的操作?
public void updateRow();?? 該方法將更新當前記錄集當前行的數據?
public void deleteRow();? 該方法將刪除當前記錄集的當前行?
public void updateString(int columnIndex String x);? 該方法更新當前記錄集當前行某列的值 該列的數據類型是 String(指 Java 數據類型是 String 與之對應的 JDBC 數據類型是VARCHAR或NVARCHAR 等數據類型) 該方法的參數 columnIndex指定所要更新的列的列索引 第一列的列索引是 1 以此類推 第二個參數 x 代表新的值 這個方法并不執行數據庫操作 需要執行 insertRow()方法或者 updateRow()方法以后 記錄集和數據庫中的數據才能夠真正更新?
public void updateString(String??? columnName String??? x);? 該方法和上面介紹的同名方法差不多 不過該方法的第一個參數是 columnName 代表需要更新的列的列名 而不是columnIndex?
ResultSet 接口中還定義了很多個 updateXXX()方法 都和上面的兩個方法相類似 由于篇幅的原因 在這里就不詳細描述了 對此感興趣的讀者 可以參考相關的文獻?
往數據庫當前記錄集插入新行的操作流程如下?
1 調用moveToInsertRow()方法?
2 調用updateXXX()方法 指定插入行各列的值?
3 調用insertRow()方法 往數據庫中插入新的行?

更新數據庫中某個記錄的值(某行的值)的方法是?
1 定位到需要修改的行(使用 absolute() relative()等方法定位)?
2 使用相應updateXXX()方法設定某行某列的新值 XXX 所代表的Java 數據類型
必須可以映射為某列的JDBC數據類型 如果希望rollback該項操作 請再調用updateRow()方法以前使用cancelRowUpdates()方法 這個方法可以將某行某列的值復原?
3 使用updateRow()方法 完成 UPDATE 的操作?
刪除記錄集中某行(亦即刪除某個記錄)的方法?
1 定位到需要修改的行(使用 absolute() relative()等方法定位)?
2 使用deleteRow()方法?
4 新的ResultSet接口添加了對 SQL3數據類型的支持
5 獲取記錄集行數的方法
1 首先使用last()方法 將數據庫游標定位到記錄集的最后一行?
2 使用 getRow()方法 返回記錄集最后一行的行索引 該索引就等于記錄集所包
含記錄的個數 也就是記錄集的行數
9.2.2? 新的SQL語句接口(Statement 接口)
在JDBC API 2.0 中 SQL語句接口(Statement接口)也有了很大的改進 功能更加強大? PreparedStatement接口和CallableStatement接口都繼承了 Statement接口 因此本小節也介紹這兩個接口相對于 JDBC API 1.0的改進之處 因為上述的三個接口都由Connection接口的方法創建 所以本小節也順便提一提 Connection接口?
1 Statement接口 CallableStatement接口 PreparesStatement接口的創建
這三個接口分別由Connection接口的createStatement() prepareStatement() prepareCall()等方法創建 這幾個方法的定義如下?
public Statement createStatement();
public Statement createStatement(int resultSetType int resultSetConcurrency);
public CallableStatement prepareCall(String sql);
public CallableStatement prepareCall(String sql int resultSetType?
int resultSetConcurrency);
public PreparedStatement prepareStatement(String sql);
public PreparedStatement prepareStatement(String sql int resultSetType?
?int resultSetConcurrency);
上面列出的方法中
參數sql代表需要執行的 SQL語句? 這些 SQL語句不是完整的
SQL 語句 一般帶有 IN/OUT/INOUT 參數 參數 resultSetType 代表該方法創建的 SQL 語句接口執行 SQL 語句所返回的 ResultSet 的類型 例如 是否允許數據庫游標前后移動是否對其他用戶的數據庫更新操作敏感等 它們都是一些整型的常數 在ResultSet接口中定義了
參數 resultSetConcurrency 代表該方法創建的SQL語句接口執行SQL語句所返回的ResultSet的協同模式 如允許更新記錄集的數據 或者僅僅只讀 不能更新等 它們也是一些整型的常數 在ResultSet接口中定義了
例?
stmt=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE?
ResultSet.CONCUR_UPDATABLE);
上面的代碼創建了一個 SQL語句接口(Statement)的實例對象 該實例對象允許它執行
SQL語句所返回的記錄集中的數據庫游標前后移動 允許更新記錄集中的數據?
2 支持批操作
Statement接口 PreparedStatement接口 CallableStatement接口都支持數據庫批操作就是將若干個 SQL 語句添加到一個 SQL 語句塊(Batch)中 一并發送到數據庫服務器去數據庫引擎執行完 SQL語句塊中的語句后 會將所有的結果一并返回 這種功能特別適用于大批量的數據庫 INSERT 操作 為了實現這樣的功能 必須用到的 Statement接口的方法
如下所示?
public void addBatch(String? sql);? 該方法用于將SQL語句添加到 SQL語句塊中?
public void clearBatch();?? 該方法用于將SQL語句塊中的所有SQL語句全部刪除?
public int[] executeBatch();? 該方法用于將 SQL語句塊發送到數據庫服務器去 并執
行它 返回的結果是一個整型數組 數組中的元素是數據庫服務器執行 SQL語句塊中SQL語句所返回的更新計數 SQL語句塊中含有多少個 SQL語句 返回的整行數組中就含有多少個元素?
使用JDBC API執行數據庫批操作的方法是?
1 創建Statement接口的實例對象?
2 調用addBatch()方法 往SQL語句塊中添加若干個SQL語句?
3 使用executeBatch()方法 完成數據庫批操作

上面介紹的執行數據庫批操作的方法僅僅適用于 Statement 接口 不適用于
PreparedStatement接口 CallableStatement接口 后面兩個接口定義了新的 addBatch()方法
該方法不需要任何參數 但是在Statement接口中定義的 addBatch()方法卻需要參數 參數是一個SQL語句 數據類型是String?
在 PreparedStatement接口 CallableStatement接口中實現數據庫批操作的方法是?
1 創建PreparedStatement接口或者CallableStatement接口的實例對象?
2 使用PreparedStatement 接口中定義的 setXXX()方法設定 SQL語句(該 SQL語句是在創建 PreparedStatement 接口或者 CallableStatement 接口的實例對象時初始化的)的IN/OUT/INOUT 參數的值(CallableStatement 接口并沒有定義任何 setXXX()方法 它的setXXX()方法全部繼承自PreparedStatement接口)??
3 使用executeBatch()方法該方法在Statement接口中定義不過PreparedStatement
接口和CallableStatement接口都繼承了這個方法?