JDBC基本教程之ResultSet工具
副标题#e#
概述
ResultSet 包括切合 SQL 语句中条件的所有行,而且它通过一套 get 要领(这些 get 要领可以会见当前行中的差异列)提供了对这些行中数据的会见。ResultSet.next 要领用于移动到 ResultSet 中的下一行,使下一行成为当前行。
功效集一般是一个表,个中有查询所返回的列标题及相应的值。譬喻,假如查询为 SELECT a, b, c FROM Table1,则功效集将具有如下形式:
a b c
-------- --------- --------
12345 Cupertino CA
83472 Redmond WA
83492 Boston MA
下面的代码段是执行 SQL 语句的示例。该 SQL 语句将返回行荟萃,个中列 1 为 int,列 2 为 String,而列 3 则为字节数组:
java.sql.Statement stmt = 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 得到光标名。
留意:不是所有的 DBMS 都支持定位更新和删除。可利用 DatabaseMetaData.supportsPositionedDelete 和 supportsPositionedUpdate 要领来查抄特定毗连是否支持这些操纵。当支持这些操纵时,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 获得其列号。
#p#副标题#e#
3、数据范例和转换
对付 getXXX 要领,JDBC 驱动措施试图将根基数据转换成指定 Java 范例,然后返回适合的 Java 值。譬喻,假如 getXXX 要领为 getString,而根基数据库中数据范例为 VARCHAR,则 JDBC 驱动措施将把 VARCHAR 转换成 Java String。getString 的返回值将为 Java String 工具。
下表显示了答允用 getXXX 获取的 JDBC 范例及推荐用它获取的 JDBC 范例(通用SQL 范例)。小写的 x 暗示答允 getXXX 要领获取该数据范例;大写的 X 暗示对该数据范例推荐利用 getXXX 要领。譬喻,除了 getBytes 和 getBinaryStream 之外的任何 getXXX 要领都可用来获取 LONGVARCHAR 值,可是推荐按照返回的数据范例利用 getAsciiStream 或 getUnicodeStream 要领。要领 getObject 将任何数据范例返回为 Java Object。当根基数据范例是特定于数据库的抽象范例或当通用应用措施需要接管任何数据范例时,它长短常有用的。
可利用 ResultSet.getXXX 要领获取常见的 JDBC 数据范例。
“x”暗示该 getXXX 要领可正当地用于获取给定 JDBC 范例。
“X”暗示推荐利用该 getXXX 要领来获取给定 JDBC 范例。
getByte X x x x x x x x x x x x x
getShort x X x x x x x x x x x x x
getInt x x X x x x x x x x x x x
getLong x x x X x x x x x x x x x
getFloat x x x x X x x x x x x x x
getDouble x x x x x X X x x x x x x
getBigDecimal x x x x x x x X X x x x x
getBoolean x x x x x x x x x X x x x
getString x x x x x x x x x x X X x x x x x x x
getBytes X X x
getDate x x x X x
getTime x x x X x
getTimestamp x x x x x
getAsciiStream x x X x x x
getUnicodeStream x x X x x x
getBinaryStream x x x
getObject x x x x x x x x x x x x x x x x x x x
4、对很是大的行值利用流
#p#分页标题#e#
ResultSet 可以获取任意大的 LONGVARBINARY 或 LONGVARCHAR 数据。要领getBytes 和 getString 将数据返回为大的块(最大为 Statement.getMaxFieldSize 的返回值)。可是,以较小的牢靠块获取很是大的数据大概会更利便,而这可通过让 ResultSet 类返回 java.io.Input 流来完成。从该流中可分块读取数据。留意:必需当即会见这些流,因为在下一次对 ResultSet 挪用getXXX 时它们将自动封锁(这是由于根基实现对大块数据会见有限制)。
JDBC API 具有三个获取流的要领,别离具有差异的返回值:
getBinaryStream 返回只提供数据库原字节而不举办任何转换的流。
getAsciiStream 返回提供单字节 ASCII 字符的流。
getUnicodeStream 返回提供双字节 Unicode 字符的流。
留意:它差异于 Java 流,后者返回无范例字节并可(譬喻)通用于 ASCII 和Unicode 字符。
下列代码演示了 getAsciiStream 的用法:
java.sql.Statement stmt = con.createStatement();
ResultSet r = stmt.executeQuery("SELECT x FROM Table2");
// 此刻以 4K 块巨细获取列 1 功效:
byte buff = new byte[4096];
while (r
// 将新填充的缓冲区发送到 ASCII 输出流:
output.write(buff, 0, size);
}
}
5、NULL 功效值
要确定给定功效值是否是 JDBC NULL,必需先读取该列,然后利用 ResultSet.wasNull 要领查抄该次读取是否返回 JDBC NULL。
当利用 ResultSet.getXXX 要领读取 JDBC NULL 时,要领 wasNull 将返回下列值之一:
Java null 值:对付返回 Java 工具的 getXXX 要领(譬喻 getString、getBigDecimal、getBytes、getDate、getTime、getTimestamp、getAsciiStream、getUnicodeStream、getBinaryStream、getObject 等)。
零值:对付 getByte、getShort、getInt、getLong、getFloat 和 getDouble。
false 值:对付 getBoolean。
6、可选功效集或多功效集
凡是利用 executeQuery(它返回单个 ResultSet)或 executeUpdate(它可用于任何数据库修改语句,并返回更新行数)可执行 SQL 语句。但有些环境下,应用措施在执行语句之前不知道该语句是否返回功效集。另外,有些已存储进程大概返回几个差异的功效集和/或更新计数。
为了适应这些环境,JDBC 提供了一种机制,答允应用措施执行语句,然后处理惩罚由功效集和更新计数构成的任意荟萃。这种机制的道理是首先挪用一个完全通用的execute 要领,然后挪用别的三个要领,getResultSet、getUpdateCount 和getMoreResults。这些要领答允应用措施一次一个地研究语句功效,并确定给定功效是 ResultSet 照旧更新计数。
为了适应这些环境,JDBC 提供了一种机制,答允应用措施执行语句,然后处理惩罚由功效集和更新计数构成的任意荟萃。这种机制的道理是首先挪用一个完全通用的execute 要领,然后挪用别的三个要领,getResultSet、getUpdateCount 和getMoreResults。这些要领答允应用措施一次一个地研究语句功效,并确定给定功效是 ResultSet 照旧更新计数。
用户不必封锁 ResultSet;当发生它的 Statement 封锁、从头执行或用于从多功效序列中获取下一个功效时,该 ResultSet 将被 Statement 自动封锁。