JSP學習——全面解析JDBC(5)
來源:互聯網
上載者:User
js 如何獲得SQL語句的執行結果?
ResultSet包含符合SQL語句中條件的所有行,並且它通過一套get方法(這些get方法可以訪問當前行中的不同列)提供了對這些行中資料的訪問。ResultSet.next方法用於移動到ResultSet中的下一行,使下一行成為當前行。
下面的程式碼片段是執行SQL語句的樣本。該SQL語句將返回行集合,其中列1為int,列2為String,而列3則為位元組數組:
Java.sql.Statementstmt=conn.createStatement();
ResultSet r=stmt.executeQuery("SELECT a,b,c FROM Table1");
while(r.next()){
//列印當前行的值。
Int i=r.getInt("a");
String s=r.getString("b");
Float f=r.getFloat("c");
System.out.println("ROW="+i+" "+s+" "+f);
}
1. 行和游標
ResultSet維護指向其當前資料行的游標。每調用一次next方法,游標向下移動一行。
最初它位於第一行之前,因此第一次調用next將把游標置於第一行上,使它成為當前行。隨著每次調用next導致游標向下移動一行,按照從上至下的次序擷取ResultSet行。
在ResultSet對象或其父輩Statement對象關閉之前,游標一直保持有效。在SQL中,結果表的游標是有名字的。如果資料庫允許定點更新或定位刪除,則需要將游標的名字作為參數提供給更新或刪除命令。可通過調用方法getCursorName獲得游標名。
DatabaseMetaData.supportsPositionedDelete和supportsPositionedUpdate方法來檢查特定串連是否支援這些操作。當DBMS支援定點更新和刪除操作時,DBMS/驅動程式必須確保適當鎖定選定行,以使定點更新不會導致更新異常或其它並發問題。
2. 列
方法getXXX提供了擷取當前行中某列值的途徑。在每一行內,可按任何次序擷取列值。但為了保證可移植性,應該從左至右擷取列值,並且一次性地讀取列值。
列名或列號可用於標識要從中擷取資料的列。例如,如果ResultSet對象rs的第二列名為"title",並將值儲存為字串,則下列任一代碼將擷取儲存在該列中的值:
String s=rs.getString("title");
String s=rs.getString(2);
注意列是從左至右編號的,並且從列1開始。同時,用作getXXX方法的輸入的列名不區分大小寫。
提供使用列名這個選項的目的是為了讓在查詢中指定列名的使用者可使用相同的名字作為getXXX方法的參數。另一方面,如果select語句未指定列名(例如在"select * from table1"中或列是匯出的時),則應該使用列號。這些情況下,使用者將無法確切知道列名。
有些情況下,SQL查詢返回的結果集中可能有多個列具有相同的名字。如果列名用作getXXX方法的參數,則getXXX將返回第一個匹配列名的值。因而,如果多個列具有相同的名字,則需要使用列索引來確保檢索了正確的列值。這時,使用列號效率要稍微高一些。
關於ResultSet中列的資訊,可通過調用方法ResultSet.getMetaData得到。返回的ResultSetMetaData對象將給出其ResultSet對象各列的編號、類型和屬性。
如果列名已知,但不知其索引,則可用方法findColumn得到其列號。
3. 資料類型和轉換
對於getXXX方法,JDBC驅動程式試圖將基本資料轉換成指定Java類型,
然後返回適合的Java值。例如,如果getXXX方法為getString,而基本資料庫中資料類型為VARCHAR,則JDBC驅動程式將把VARCHAR轉換成JavaString。getString的傳回值將為JavaString對象。
4. 對非常大的行值使用流
ResultSet可以擷取任意大的LONGVARBINARY或LONGVARCHAR資料。方法getBytes和getString將資料返回為大的塊(最大為Statement.getMaxFieldSize的傳回值)。但是,以較小的固定塊擷取非常大的資料可能會更方便,而這可通過讓ResultSet類返回Java.io.Input流來完成。從該流中可分塊讀取資料。注意:必須立即訪問這些流,因為在下一次對ResultSet調用getXXX時它們將自動關閉(這是由於基本實現對大塊資料訪問有限制)。
JDBCAPI具有三個擷取流的方法,分別具有不同的傳回值:
·getBinaryStream:返回只提供資料庫原位元組而不進行任何轉換的流。
·getAsciiStream返回提供單位元組ASCII字元的流。
·getUnicodeStream返回提供雙位元組Unicode字元的流。
注意:它不同於Java流,後者返回無類型位元組並可(例如)通用於ASCII和Unicode字元。下列代碼示範了getAsciiStream的用法:
Java.sql.Statementstmt=con.createStatement();
ResultSet r=stmt.executeQuery("SELECT x FROM Table2");
//現在以4K塊大小擷取列1結果:
byte buff=newbyte[4096];
while(r.next()){
Java.io.InputStream fin=r.getAsciiStream(1);
for(;;){
intsize=fin.read(buff);
if(size==-1){//到達流末尾
break;
}
//將新填充的緩衝區發送到ASCII輸出資料流:
output.write(buff,0,size);
}
}
5. NULL結果值
要確定給定結果值是否是JDBC NULL,必須先讀取該列,然後使用ResultSet.wasNull
方法檢查該次讀取是否返回JDBC NULL。
當使用ResultSet.getXXX方法讀取JDBC NULL時,方法wasNull將返回下列值之一:
(1)Javanull值
對於返回Java對象的getXXX方法(例如getString、getBigDecimal、getBytes、getDate、getTime、getTimestamp、getAsciiStream、getUnicodeStream、getBinaryStream、getObject等)。
(2)零值:對於getByte、getShort、getInt、getLong、getFloat和getDouble。
(3)false值:對於getBoolean。
6. 可選結果集或多結果集
通常使用executeQuery(它返回單個ResultSet)或executeUpdate(它可用於任何資料庫修改語句,並返回更新行數)可執行SQL語句。但有些情況下,應用程式在執行語句之前不知道該語句是否返回結果集。此外,有些已預存程序可能返回幾個不同的結果集和/或更新計數。
為了適應這些情況,JDBC提供了一種機制,允許應用程式執行語句,然後處理由結果集和更新計數組成的任意集合。這種機制的原理是首先調用一個完全通用的execute方法,然後調用另外三個方法,getResultSet、getUpdateCount和getMoreResults。這些方法允許應用程式一次一個地研究語句結果,並確定給定結果是ResultSet還是更新計數。
使用者不必關閉ResultSet;當產生它的Statement關閉、重新執行或用於從多結果序列中擷取下一個結果時,該ResultSet將被Statement自動關閉。