JDBCTM 指南:入门5 - ResultSet

网络编程 2025-04-25 02:18www.168986.cn编程入门

这篇文章是从《JDBC Database Access from Java: A Tutorial and Annotated Reference》一书中摘取的,该书目前正在由JavaSoft准备,并计划在1997年春季由Addison-Wesley出版公司作为Java系列的一部分出版。这本书既是一个教程,也是JDBC的重要参考手册。

在编程实践中,当我们执行一个SQL查询语句,如"SELECT a, b, c FROM Table1",返回的ResultSet将按照a、b、c的列名和相应的值组织。我们可以通过狼蚁网站SEO优化的代码段来演示如何遍历并操作这个ResultSet。例如:

```java

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);

}

```

关于ResultSet的内部机制,它维护了一个指向当前数据行的光标。每调用一次next方法,光标就会向下移动一行。最初,光标位于第一行之前,第一次调用next会将光标置于第一行,使其成为当前行。随着每次调用next,光标会按照从上到下的顺序遍历ResultSet的行。在ResultSet对象或其父级Statement对象关闭之前,光标始终保持有效。

在SQL中,结果表的光标是有名字的。如果数据库支持定位更新或定位删除,则需要将光标的名字作为参数提供给更新或删除命令。可以通过getCursorName方法获取光标名。值得注意的是,并非所有的DBMS都支持定位更新和删除。是否支持这些操作可以通过DatabaseMetaData的supportsPositionedDelete和supportsPositionedUpdate方法来检查。当支持这些操作时,DBMS/驱动程序会确保适当锁定选定行,以避免定位更新导致的更新异常或其他并发问题。

对于列的操作,getXXX方法提供了获取当前行中某列值的途径。用户可以在一行内按任何顺序获取列值,但为了保持代码的可移植性,建议从左到右获取,并一次性读取列值。列可以通过列名或列号来标识,以便获取数据。例如,如果第二列名为"title",则可以通过以下任一方式获取该列的值:

```java

String s = rs.getString("title");

// 或

String s = rs.getString(2);

```

值得注意的是,列是从左到右编号的,并且从列1开始。用作getXXX方法输入的列名不区分大小写。提供列名选项的目的是为了让在查询中指定列名的用户可以使用相同的名字作为getXXX方法的参数。另一方面,如果select语句未指定列名(例如在"select from table1"中),或者列是导出的,则应该使用列号来获取值。在这些情况下,用户无法确切知道列名。如果结果集中有多个列具有相同的名字,那么需要使用列索引来确保检索正确的列值。这时,使用列号可能会更有效率。关于ResultSet中列的信息,可以通过ResultSet的getMetaData方法获得,返回的ResultSetMetaData对象将给出ResultSet对象各列的编号、类型和属性。如果知道列名但不知道其索引,可以使用findColumn方法获得其列号。在数据世界中,JDBC驱动程序发挥着关键的角色,尤其在处理数据库中的数据转换时。对于getXXX方法,它致力于将基础数据类型转换为指定的Java类型,并返回相应的Java值。这一流程如同一个巧妙的翻译器,将数据库的方言转化为Java能够理解的语言。

例如,当我们在数据库中有一个VARCHAR类型的数据,而我们需要用Java来获取它时,JDBC驱动程序就会用getString方法将其转换为Java String。这样,我们就能够在Java程序中轻松地使用这个字符串了。

接下来,让我们仔细看看这些getXXX方法的用途和推荐用途。它们如同数据世界的瑞士军刀,每一种类型都有特定的用途。方法getObject是个万能工具,它能将任何数据类型返回为Java Object,这在处理特定于数据库的抽象类型或通用应用程序时特别有用。

当处理非常大的行值时,如LONGVARBINARY或LONGVARCHAR数据,使用流的方式非常实用。想象你正在处理一个巨大的文档或图像文件,一次性读取可能会导致内存不足。这时,你可以让ResultSet类返回一个java.io.Input流,然后分块读取数据。这种方式在处理非常大的数据时非常便利。但要注意,这些流必须在下次对ResultSet调用getXXX之前访问,因为它们会在此后自动关闭。这是因为对于大块数据的访问,基础实现有一定的限制。

JDBC API提供了三种获取流的方法,它们具有不同的返回值和用途。getBinaryStream返回原始字节流,不进行任何转换。getAsciiStream返回单字节ASCII字符流,而getUnicodeStream则返回双字节Unicode字符流。这些流方法为我们提供了灵活的方式来处理不同类型的数据,使我们能够轻松地在Java应用程序和数据库之间传输数据。

想象一下,我们正在从数据库中的“Table2”表中查询数据,并想要以块的形式获取列1的ASCII流数据。这个过程就像是一场数据的舞蹈,需要我们细致地操控每一步。

我们创建一个JDBC的Statement对象来与数据库交互,然后通过执行查询语句得到一个ResultSet对象,它就像一个存储了查询结果的容器。现在,我们想要从这个容器中提取数据。

对于列1的数据,我们知道它包含ASCII流信息。于是,我们创建一个输入流对象fin来读取这个流。这个输入流以4K的块大小读取数据,就像是在读取一段段的数据段落。当读取到流的末尾时,read方法会返回-1,这时我们就知道已经读取完毕。

接下来,我们将读取到的数据块发送到ASCII输出流中。这就像是在舞台上表演一场数据的魔术秀,将字节转化为可见的字符。

在处理结果集时,我们还要面对一个问题:如何确定给定的结果值是否是JDBC的NULL值呢?这就需要我们先读取该列,然后使用ResultSet的wasNull方法来检查这次读取是否返回了JDBC的NULL值。这个方法会根据不同的getXXX方法返回不同的值。例如,对于返回Java对象的getXXX方法,如果返回的是JDBC NULL,那么wasNull会返回Java的null值。

在某些情况下,我们的SQL语句可能会返回多个结果集或者更新计数。这对于那些在执行语句之前不确定语句是否会返回结果集的应用程序来说是一个挑战。JDBC提供了一种机制来处理这种情况,允许应用程序执行语句后,通过调用getResultSet、getUpdateCount和getMoreResults等方法来处理任意的结果集和更新计数集合。这就像是在表演一场复杂的数据芭蕾舞,需要精确操控每一步。

最后要注意的是,当我们处理完一个ResultSet后,不需要手动关闭它。当产生它的Statement被关闭、重新执行或者用于从多结果序列中获取下一个结果时,这个ResultSet会被自动关闭。这就像是一场演出的谢幕,一切都在有序地进行着。

至于提到的“cambrian.render('body')”,看起来像是某种特定的渲染指令或函数调用,但没有更多的上下文信息很难给出准确的解释。如果是在某个特定的框架或环境中使用,可能需要查阅相关的文档或资料来了解其具体的用途和用法。

上一篇:利用PHP实现开心消消乐的算法示例 下一篇:没有了

Copyright © 2016-2025 www.168986.cn 狼蚁网络 版权所有 Power by