管理当前行

我们编写了第一个程序并且运行良好。我们编写了一个查询,执行了它,结果executeQuery()方法返回了一个对象给我们结果集包含所有查询结果的 。现在我们将尝试弄清楚如何从中获得这些结果。

查询结果可能包含各种类型的数千行和数百列,因此这并不像您想象的那么简单。例如,图片可以存储在数据库中,然后您可以将图片作为一组字节或InputStream来下载。

但我们将从最简单的开始——“当前结果行”的概念。由于结果通常有很多行,因此对象结果集里面有一个指向当前行的指针。并顺序切换行以使用next()方法读取它们。

这种方法主要是为了优化。在您按顺序读取字符串之前,JDBC 驱动程序可能不会从数据库中加载字符串。您也从头到尾按顺序阅读FileInputStream 。因此,您应该熟悉并理解这种方法。

但是,如果您确实需要它,则可以使用RandomAccessFile类在任何地方读取文件。

ResultSet类也允许类似的东西,并允许您将当前行沿着结果移动到任何地方。为此,它有以下方法:

方法 描述
1个 下一个() 切换到下一行
2个 以前的() 切换到上一行
3个 isFirst() 当前行优先?
4个 isBeforeFirst() 我们在第一线前面吗?
5个 最后一个() 当前行是最后一行吗?
6个 isAfterLast() 我们在截止日期之后吗?
7 绝对(int n) 使第 N 行成为当前行
8个 相对(int n) 将当前行向前移动 N 个位置。N 可以小于 0
9 获取行() 返回行号

方法很简单,但是需要说明两点。结果就像两边的空线框起来一样。因此,最初当前行在结果的第一行之前。要获得第一行,您需要至少调用一次next()方法。

如果您在最后一行调用了next()方法,那么您将移动到最后一行之后的行。您无法从中读取数据,但不会发生错误。这里的isAfterLast()方法将声明 true 作为结果。

例子:

Statement statement = connection.createStatement();
ResultSet results = statement.executeQuery("SELECT * FROM user");

System.out.println( results.getRow() );        	// 0
System.out.println( results.isBeforeFirst() );  // true
System.out.println( results.isFirst() );          	// false

results.next();

System.out.println( results.getRow() );        	// 1
System.out.println( results.isBeforeFirst() );  // false
System.out.println( results.isFirst() );          	// true

results.next();

System.out.println( results.getRow() );        	// 2
System.out.println( results.isBeforeFirst() );  // false
System.out.println( results.isFirst() );          	// false

从当前行获取数据

您已经学会了熟练地管理当前行。现在让我们弄清楚如何从中获取数据。为此,对象结果集有一些特殊的方法可以用一个模板来描述:

getType(numberColumns)

但是,如果列有名称,那么您也可以通过列名获取:

getType(nameColumns)

例子:

while (results.next()) {
        	Integer id = results.getInt(“id”);
        	String name = results.getString(“name”);
        	System.out.println(results.getRow() + ". " + id + "\t"+ name);
}

下面我将提供一个表格,帮助您关联 SQL 数据类型和 ResultSet 方法:

SQL数据类型 getXXX() 方法
字符 获取字符串()
变量 获取字符串()
情报局 获取整数()
漂浮 getDouble()
CLOB 得到Clob()
BLOB 获取Blob()
日期 获取日期()
时间 获取时间()
时间戳 获取时间戳()

重点,我想你明白了。

获取有关 ResultSet 的不同数据

我们想出了如何从当前行读取数据:通过列号和名称。顺便说一句,我怎样才能通过编号找到列名?或者结果中的列数?

一方面,如果你写了一个请求,那么你似乎必须知道这一切。另一方面,我们可以编写一个在屏幕上显示查询结果的程序:查询被传递给我们,我们只想在屏幕上(在控制台、网页中)显示 SQL 服务器返回的所有内容给我们。

JDBC 为此有一个特殊的对象,即ResultSetMetaData接口。获取这种类型的对象非常简单:

Statement statement = connection.createStatement();
ResultSet results = statement.executeQuery("SELECT * FROM user");
ResultSetMetaData resultSetMetaData = results.getMetaData();

ResultSetMetaData接口有一些非常有趣的方法。以下是最受欢迎的:

1个 getColumnCount() 返回结果列数
2个 getColumnName(整数列) 返回列名
3个 getColumnLabel(整数列) 返回列的描述
4个 getColumnType() 返回列类型:数字(特殊代码)
5个 getColumnTypeName() 返回列类型:字符串
6个 getColumnClassName() 返回列类型的 java 类名
7 获取表名() 返回表名
8个 获取目录名称() 返回列的目录名称
9 获取架构名称() 返回数据库的模式名称
10 isAutoIncrement(整数列) 该列是否支持 AUTO INCREMENT?
十一 可空() 列可以包含 NULL 吗?

让我们用它来了解一下我们的表:

ResultSetMetaData metaData = results.getMetaData();
int columnCount = metaData.getColumnCount();
for (int column = 1; column <= columnCount; column++)
{
        	String name = metaData.getColumnName(column);
        	String className = metaData.getColumnClassName(column);
        	String typeName = metaData.getColumnTypeName(column);
        	int type = metaData.getColumnType(column);

        	System.out.println(name + "\t" + className + "\t" + typeName + "\t" + type);
}

重要的!请注意,列是从 1 开始编号的。顺便说一下,行也是如此。这有多不寻常,对吧?

这是我运行程序后得到的结果:

“C:\Program Files\Java\jdk-17.0.3.1\bin\java.exe...
ID java.lang.整数 情报局 4个
姓名 java.lang.字符串 变量 12
等级 java.lang.整数 情报局 4个
创建日期 java.sql.日期 日期 91
进程结束,退出代码为 0