管理当前行
我们编写了第一个程序并且运行良好。我们编写了一个查询,执行了它,结果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 |
GO TO FULL VERSION