ResultSet用來從查詢語句中獲取結果。對ResultSet的操作是反應到數據庫遊標(cursor)上的。
1.ResultSet分類
ResultSet可從三方面分類,分別是Types,Concurrency ,Holdability
ResultSet Types
從兩個方面分類 1.操作的光標方式 2.數據庫併發數據修改後ResultSet 的反饋。
ResultSet.TYPE_FORWARD_ONLY
:Cursor 只能往前移動, 默認值
ResultSet.TYPE_SCROLL_INSENSITIVE
: Cursor 可以前後移動, 但是對於數據庫的改動不關心.
ResultSet.TYPE_SCROLL_SENSITIVE
: Cursor 可以前後移動, 並且當數據庫發生改動(僅update)的時候, ResultSet也會隨之更新。
推薦這篇文章——文章鏈接,詳細介紹了ResultSet.TYPE_SCROLL_SENSITIVE
,但要注意 : mysql是不支持ResultSet.TYPE_SCROLL_SENSITIVE的!,可以使用Ms-SqlServer等其他DB測試。
DatabaseMetaData#supportsResultSetType(int ResultSetType) 可以測試你使用的數據庫支持哪些ResultSet Types
ResultSet Concurrency
用來描述我們是否可以更新結果集中的數據到數據庫. 有兩個值可以用:
ResultSet.CONCUR_READ_ONLY
: 結果集是隻讀的
ResultSet.CONCUR_UPDATABLE
: 結果集是可以更新的
Cursor Holdability
這個屬性是關於事務提交後, 是否需要關閉結果集。
HOLD_CURSORS_OVER_COMMIT
: 當調用 Connection.commit()後, ResultSet 將不會關閉, 一般用於只讀的結果集中.
CLOSE_CURSORS_AT_COMMIT
: 當調用 Connection.commit()後, ResultSet 將會關閉
指定ResultSet Types/Concurrency /Holdability
可以使用Connection的createStatement方法指定:
Statement createStatement(int resultSetType, int resultSetConcurrency);
Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability);
也有生成PreparedStatement,CallableStatement類似的方法。
2.創建和操作ResultSet
遊標
一個ResultSet包含了一個遊標,當ResultSet被創建的時候,遊標位於第一行數據的前面。ResultSet的一些方法對應了遊標的移動:
ResultSet方法 | 解釋 |
---|---|
boolean next() | 該方法的作用是將數據庫遊標向前移動一位,使得下一行成爲當前行,當剛剛打開記錄集對象時,數據庫遊標的位置在記錄集的最前面,第一次使用next()方 法將會使數據庫遊標定位到記錄集的第一行,第二次使用next()方法將會使數據庫遊標定位到記錄集的第二行,以此類推。 |
boolean previous() | 該方法的作用是將數據庫遊標向後移動一位,使得上一行成爲當前行. |
boolean first() | 該方法的作用是將當前行定位到數據庫記錄集的第一行。 |
boolean last() | 該方法的作用剛好和first()方法相反 |
void beforeFirst() | 該方法的作用是將數據庫遊標移到記錄集的最前面,位於記錄集第一行的前面,如果記錄集不包含任何的行該方法不產生作用。 |
void afterLast() | 該方法的作用是將數據庫遊標移到記錄集的最後,位於記錄集最後一行的後面,如果該記錄集不包含任何的行該方法不產生作用。 |
boolean absolute(int row) | 該方法的作用是將記錄集中的某一行設定爲當前行,亦即將數據庫遊標移動到指定的行,參數row 指定了目標行的行號,這是絕對的行號,由記錄集的第一行開始計算不是相對的行號. |
boolean relative(int rows) | 該方法的作用也是將記錄集中的某一行設定爲當前行,但是它的參數rows 表示目標行相對於當前行的行號。 |
獲取值
根據列順序獲取(順序號從1開始):
while (resultSet.next()){
System.out.println(resultSet.getString(1)+"\t"+resultSet.getInt(2));
}
根據列名稱獲取:
while (resultSet.next()){
System.out.println(resultSet.getString("name")+"\t"+resultSet.getInt("age"));
}
根據列名稱獲取順序號:
int nameIndex = resultSet.findColumn("name");//返回1
int weightIndex = resultSet.findColumn("weight");//拋出異常
注意:根據列名稱獲取一般先通過findColumn來獲取順序號,然後再根據列順序獲取得列值。所以在性能要求高的時候,儘量根據列順序獲取列值,當然,這降低了可讀性。
修改
如果創建Statement時候制訂了ResultSet.CONCUR_UPDATABLE,則通過ResultSet可以修改表數據。
修改:
resultSet.next();
resultSet.updateString("name","XXXXXX");
resultSet.updateRow();
同樣,ResultSet也可以刪除數據,對應的方法有ResultSet#deleteRow();
插入一行演示:
resultSet.moveToInsertRow();
resultSet.updateString(1, "XiaoMing");
resultSet.updateInt(2, 25);
resultSet.insertRow();
關閉ResultSet
下列情況下,ResultSet會被關閉:
1. 當執行ResultSet#close方法時候。
2. 創建該ResultSet的Statement和Connection被關閉時候。
3. Statement被重新執行。
4. Statement指定了CLOSE_CURSORS_AT_COMMIT,並提交。