From Gossip@Openhome

Java Gossip: ResultSet 游標控制

之前在建立Statement或 PreparedStatement,您所使用的是Connection無參數的createStatement()與 preparedStatement(),這樣取得的Statement其執行SQL後得到的ResultSet,將只能使用next()方法逐筆取得查 詢結果。

您可以在建立Statement物件時指定resultSetType,可指定的參數有 ResultSet.TYPE_FORWARD_ONLY、ResultSet.TYPE_SCROLL_INSENSITIVE與 ResultSet.TYPE_SCROLL_SENSITIVE,在不指定的情況下,預設是第一個,也就是只能使用next()來逐筆取得資料,指定第二個或第三個,則可以使用ResultSet的afterLast()、previous()、absolute()、relative()等方法。

ResultSet.TYPE_SCROLL_INSENSITIVE與ResultSet.TYPE_SCROLL_SENSITIVE 的差別在於能否取得ResultSet改變值後的資料,另外您還必須指定resultSetConcurrency,有 ResultSet.CONCUR_READ_ONLY與ResultSet.CONCUR_UPDATABLE兩個參數可以設定,前者表示只能讀取 ResultSet的資料,後者表示可以直接使用ResultSet來操作資料庫,這會在下一個主題後說明。

createStatement()不給定參數時,預設是ResultSet.TYPE_FORWARD_ONLY、 ResultSet.CONCUR_READ_ONLY。

這邊先示範如何控制ResultSet的讀取游標,在建立Statement時,您使用 ResultSet.TYPE_SCROLL_INSENSITIVE及ResultSet.CONCUR_READ_ONLY即可,下面這個例子示範從 查詢到的資料最後一筆開始往前讀取:
Statement stmt = conn.createStatement(
                          ResultSet.TYPE_SCROLL_INSENSITIVE, 
                          ResultSet.CONCUR_READ_ONLY);
ResultSet result = stmt.executeQuery(
                          "SELECT * FROM message");
result.afterLast();
while(result.previous()) {
     System.out.print(result.getString("name") + "\t");
     System.out.print(result.getString("email") + "\t");
     System.out.print(result.getString("subject") + "\t");
     System.out.print(result.getString("time") + "\t");
     System.out.println(result.getString("memo") + "\t");
}
stmt.close();
conn.close();
 

afterLast()會將ResultSet的讀取游標移至最後一筆資料之後,您使用previous()方法往前移動讀取游標。

您也可以使用absolute()方法指定查詢到的資料之位置,例如absolute(4)表示第四筆資料,absoulte(10)則是第十筆資料,如果指定負數,則從最後往前數,例如absolute(-1)則是最後一筆資料,若有100筆資料,absoulte(-4)則是第97筆資料。

relative()方法則從目前游標處指定相對位置,例如若目前在第25筆資料,則relative(-2)則表示第23筆資料,而relative (4)則表示第29筆資料。

另外還有beforeFirst(),可以將游標移至資料的第一筆之前,first()可以將游標移至第一筆資料,而last()可以將游標移至最後一筆資料。