C語言中文網 目錄
JSP教程
1 JSP是什么
2 JSP的特點與工作流程
3 JSP與ASP、PHP的比較
4 JSP頁面的組成及其元素
5 JSP開發環境搭建
6 第一個JSP程序
7 JSP注釋
8 JSP聲明
9 JSP中嵌入Java代碼
10 JSP表達式
11 JSP開發模式
12 JSP常見錯誤
13 JSP指令
14 JSP page指令
15 JSP include指令
16 JSP指令應用實例
17 JSP動作
18 JSP include動作
19 JSP param動作
20 JSP forward動作
21 JSP plugin動作
22 JSP useBean動作
23 JSP setProperty動作
24 JSP getProperty動作
25 JSP application 對象
26 JSP out對象
27 JSP request對象
28 JSP response對象
29 JSP session對象
30 JSP pageContext對象
31 JSP page對象
32 JSP config對象
33 JSP獲取并顯示字符串長度
34 什么是JavaBean
35 JavaBean工具
36 JavaBean規范
37 JavaBean屬性
38 JavaBean Scope屬性
39 JavaBean事件
40 JavaBean實現用戶登錄界面
41 Servlet是什么
42 Servlet生命周期
43 Servlet的類和方法
44 Servlet客戶端跳轉
45 EL是什么
46 EL表達式的基本語法及運算符的優先級
47 JSP EL 點(.)運算符和下標([])運算符
48 JSP EL算數運算符
49 JSP EL關系運算符
50 JSP EL邏輯運算符
51 JSP EL條件運算符
52 JSP EL empty空運算符
53 EL表達式中的常量與變量
54 EL表達式的保留字
55 EL表達式的內置對象及其作用域
56 使用EL表達式訪問JavaBean
57 使用EL表達式訪問集合
58 EL表達式內置對象param和paramValues
59 EL表達式內置對象cookie
60 EL表達式內置對象initParam
61 JDBC 的定義及產品組件
62 建立JDBC連接
63 利用JDBC發送SQL語句
64 JDBC API ResultSet接口
65 JDBC RowSet接口
66 JDBC BaseRowSet類和CachedRowSet類
67 填充CachedRowSet對象記錄集
68 File類
69 使用字節流讀/寫文件
70 RandomAccessFile 類
71 JSP文件上傳
72 XML是什么
73 XML的基本語法
74 JDK 中的 XML API
75 DOM解析XML
76 SAX解析XML
77 DOM4j解析XML
首頁 > JSP教程 閱讀:112

JDBC API ResultSet接口(記錄集接口)

在 JDBC API 2.0 中,ResultSet 接口有了很大的變化,增加了很多行操作、行定位的新方法,功能也強大了許多,下面我們就詳細地對其進行介紹。

1. 新定義了若干個常數

在 JDBC API 2.0 中,新定義了許多常數用來指定 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;


上述新定義的常數其游標移動的方向等性質如下:
  1. fetch_forward:該常數的作用是指定處理記錄集中行的順序是由前到后,即從第一行開始處理,一直到最后一行。
  2. fetch_reverse:該常數的作用是指定處理記錄集中行的順序是由后到前,即從最后一行開始處理一直到第一行。
  3. fetch_unknown:該常數的作用是不指定處理記錄集中行的順序,由 JDBC 驅動程序和數據庫系統決定。
  4. type_forward_only:該常數的作用是指定數據庫游標的移動方向是向前,不允許向后移動,即只能使用 ResultSet 接口的 next() 方法,而不能使用 previous() 方法,否則會產生錯誤。
  5. type_scroll_insensitive:該常數的作用是指定數據庫游標可以在記錄集中前后移動,并且當前數據庫用戶獲取的記錄集對其他用戶的操作不敏感。就是說當前用戶瀏覽記錄集中的數據的同時,其他用戶更新了數據庫中的數據,但是當前用戶所獲取的記錄集中的數據不會受到任何影響。
  6. type_scroll_sensitive:該常數的作用是指定數據庫游標可以在記錄集中前后移動,并且當前數據庫用戶獲取的記錄集對其他用戶的操作敏感。就是說,當前用戶正在瀏覽記錄集,若其他用戶的操作使數據庫中的數據發生了變化,則當前用戶所獲取的記錄集中的數據也會同步發生變化。這樣有可能會導致非常嚴重的錯誤,建議慎重使用該常數。
  7. concur_read_only:該常數的作用是指定當前記錄集的協作方式(concurrency mode)為只讀,一旦使用了這個常數,則不可以更新記錄集中的數據。
  8. concur_updatable:該常數的作用是指定當前記錄集的協作方式(concurrency mode)為可以更新,一旦使用了這個常數,就可以使用 updateXXX() 等方法更新記錄集中的數據。

2. ResultSet接口提供了一整套的定位方法

這些定位方法可以在記錄集中定位到任意一行,具體有 public boolean absolute(int row)、public boolean relative(int rows) 等方法,如下表所示:

表1 ResultSet接口提供的定位方法
方法 作用
public boolean absolute(int row) 該方法的作用是將記錄集中的某一行設定為當前行,亦即將數據庫游標移動到指定的行參數
row 指定的目標行的行號,這是絕對的行號,由記錄集的第一行開始計算。
public boolean relative(int rows) 該方法的作用也是將記錄集中的某一行設定為當前行,但是它的參數 rows 表示目標行相對
于當前行的行號。
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() 方法,將會使數據庫游標定位到記錄集的第二行;以此類
推。
public boolean previous() 該方法的作用是將數據庫游標向后移動一位,使得上一行成為當前行。


注意,在 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() 方法的參數,如果是正數,那么數據庫游標向前移動;如果是負數,那么數據庫游標向后移動。

【例1】使用 ResultSet 接口的方法在記錄集中定位到特定的行。dbScroll.jsp 的代碼如下:
<%--File Name:Application.java--%>
<%@page import="java.sql.*" %>
<%
String url="jdbc:weblogic:mssqlserver4:rainbow:1433";
Connection con;
Statement stmt;
try
{
    Class.forName("weblogic.jdbc.mssqlserver4.Driver ");
}
catch(java.lang.ClassNotFoundException e)
{
    out.print("ClassNotFoundException: ");
    out.println(e.getMessage());
}
try
{
    con=DriverManager .getConnection (url "sa" "");
    stmt=con.createStatement (ResultSet.TYPE_SCROLL_SENSITIVE
    ResultSet.CONCUR_READ_ONLY);
    ResultSet srs=stmt.executeQuery("USE fancy SELECT * FROM goods");
    srs.absolute(4);
    int rowNum=srs.getRow();    //rowNum should be 4
    out.println("rowNum should be 4"+rowNum);
    srs.relative(-3);
    rowNum=srs.getRow();    //rowNum should be 1
    out.println("rowNum should be 1"+rowNum);
    srs.relative(2);
    rowNum=srs.getRow();    //rowNum should be 3
    out.println("rowNum should be 3"+rowNum);
    srs.absolute(1);
    out.println("after last?"+srs.isAfterLast());
    if(!srs.isAfterLast())
    {
        String name=srs.getString("goodsname");
        float price=srs.getFloat("price");
        out.println(name+" "+price);
    }
    srs.afterLast();
    while (srs.previous())
    {
        String name=srs.getString("goodsname");
        float price=srs.getFloat("price");
        out.println(name+" "+price);
    }
    srs.close();
    stmt.close();
    con.close();
}
catch(BatchUpdateException b)
{
    out.println("-----BatchUpdateException-----");
    out.println("SQL State:"+b.getSQL State());
    out.println("Message:"+b.getMessage());
    out.println("Vendor:"+b.getErrorCode());
    out.print("Update counts: ");
    int [] updateCounts=b.getUpdateCounts();
    for(int i=0;i<updateCounts.length;i++)
    {
        out.print(updateCounts[i]+" ");
    }
    out.println("");
}
catch(SQL Exception ex)
{
    out.println("-----SQL Exception-----");
    out.println("SQL State:"+ex.getSQL State());
    out.println("Message:"+ex.getMessage());
    out.println("Vendor:"+ex.getErrorCode());
}
%>

dbScroll.jsp 的運行環境是 BEA WebLogic Server,數據庫服務器是 Microsoft SQL Server 2010,主機名為 rainbow,數據庫服務器偵聽端口為 1433,數據庫的名稱是 fancy,創建 fancy 數據庫的 SQL 文件是 db.sql。讀者不能使用 JDBC-ODBC 橋驅動程序,否則會出錯。

3. ResultSet接口添加了對行操作的支持

使用 JDBC API 不僅可以將數據庫游標定位到記錄集中的特定行,而且還可以使用 ResultSet 接口新定義的一套方法更新當前行的數據。ResultSet 接口對數據庫的基本操作方法如下表所示。

表2 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 columnlndex,String x) 該方法更新當前記錄集當前行某列的值,該列的數據類型是 String
(指 Java 數據類型是 String,與之對應的 JDBC 數據類型是
VARCHAR 或 NVARCHAR 等)。該方法的參數 columnIndex 指
定所要更新的列的列索引,第一列的列索引是 1,以此類推;第二
個參數 x 代表新的值。這個方法并不執行數據庫操作,需要執行
insertRow() 方法或者 updateRow() 方法以后,記錄集和數據庫中
的數據才能夠真正更新。
public void updateString(String columnName,String x) 該方法和上面介紹的同名方法差不多,不過該方法的第一個參數是
cohmnName,代表需要更新的列的列名而不是 columnIndex。

ResultSet 接口中還定義了多個 updateXXX() 方法,都和上面的兩個方法類似,由于篇幅的原因,這里不再詳細描述。

在數據庫的當前記錄集插入新行的操作流程如下:
  • 調用 moveToInsertRow() 方法。
  • 調用 updateXXX() 方法指定插入行各列的值。
  • 調用 insertRow() 方法往數據庫中插入新的行。

【例2】實現在數據庫中插入新的行(亦即新的記錄)。insertRow.jsp 的代碼如下:
<%@page import="java.sql.*" %>
<%
String url="jdbc:weblogic:mssqlserver4:rainbow:1433";
Connection con;
Statement stmt;
try
{
    Class.forName("weblogic.jdbc.mssqlserver4.Driver ");
}
catch(java.lang.ClassNotFoundException e)
{
    out.println("ClassNotFoundException: ");
    out.println(e.getMessage());
}
try
{
    con=DriverManager.getConnection (url "sa" "");
    stmt=con.createStatement (ResultSet.TYPE_SCROLL_SENSITIVE
    ResultSet.CONCUR_UPDATABLE);
    ResultSet uprs=stmt.executeQuery("USE fancy SELECT * FROM tbuser");
    uprs.moveToInsertRow();
    uprs.updateString("username" "peking");
    uprs.updateString(2 "peking");
    uprs.insertRow();
    uprs.updateString(1 "lijishan");
    uprs.updateString("password" "lijishan");
    uprs.insertRow();
    uprs.beforeFirst();
    out.println("Table tbuser after insertion:");
    while (uprs.next())
    {
        String name=uprs.getString("username");
        String pass=uprs.getString("password");
        out.println("username:"+name+"<br>");
        out.println("password:"+pass+"<br>");
    }
    uprs.close();
    stmt.close();
    con.close();
}
catch(SQL Exception ex)
{
    out.println("SQL Exception:"+ex.getMessage());
}
%>

insertRow.jsp 向 fancy 數據庫的 tbuser 表插入了兩行,亦即兩個記錄,然后執行數據庫查詢,檢查 INSERT 操作對數據庫的影響,insertRow.jsp 程序應用了上面講述的方法,比較簡單,這里就不重復介紹程序中所用到的各個方法了。

更新數據庫中某個記錄的值(某行的值)的方法如下:
  • 定位到需要修改的行(使用 absolute()、relative() 等方法定位)。
  • 使用相應的 updateXXX() 方法設定某行某列的新值,XXX 所代表的 Java 數據類型必須可以映射為某列的 JDBC 數據類型,如果希望 rollback 該項操作,需要再調用 updateRow() 方法以前使用的 cancelRowUpdates() 方法,這個方法可以將某行某列的值復原。
  • 使用 updateRow() 方法,完成 UPDATE 的操作。

刪除記錄集中某行(亦即刪除某個記錄)的方法是定位到需要修改的行(使用 absolute()、relative()等方法定位),使用 deleteRow() 方法刪除。

4. 新的ResultSet接口添加了對SQL 3數據類型的支持

SQL 3 技術規范中添加了若干個新的數據類型,如 REF、ARRAY 等。

ResultSet 接口擴充了 getXXX() 方法,添加獲取數據的 getXXX() 方法有:getARRAY()、getBlob()、getBigDecimal()、getClob()、getRef(),這些方法既可以接收列索引為參數,也可以接收列名(字段名)為參數,這些方法分別返回對應的 Java 對象實例,如 ClobARRAY(JDBC ARRAY)、Blob、BigDecimal、Ref 等,使用起來十分方便。這些方法的用法在下面還會涉及,這里就不再贅述了。

5. 獲取記錄集行數的方法

使用 last() 方法,將數據庫游標定位到記錄集的最后一行。

使用 getRow() 方法,返回記錄集最后一行的行索引。該索引就等于記錄集所包含記錄的個數。

精美而實用的網站,提供C語言C++STLLinuxShellJavaGo語言等教程,以及socketGCCviSwing設計模式JSP等專題。

Copyright ?2011-2018 biancheng.net, 陜ICP備15000209號

底部Logo