处理结果集
本章主要介绍结果集的处理方式。
设置结果集类型
不同类型的结果集有各自的应用场景,应用程序需要根据实际情况选择相应的结果集类型。在执行SQL语句过程中,都需要先创建相应的语句对象,而部分创建语句对象的方法提供了设置结果集类型的功能。
创建一个Statement对象,该对象将生成具有给定类型和并发性的ResultSet对象。
createStatement(int resultSetType, int resultSetConcurrency);
创建一个PreparedStatement对象,该对象将生成具有给定类型和并发性的ResultSet对象。
prepareStatement(String sql, int resultSetType, int resultSetConcurrency);
创建一个CallableStatement对象,该对象将生成具有给定类型和并发性的ResultSet对象。
prepareCall(String sql, int resultSetType, int resultSetConcurrency);
结果集类型 resultSetType
与结果集并发 resultSetConcurrency
的取值如下表所示。
表-1 结果集类型
参数名 | 说明 |
---|---|
resultSetType | 表示结果集的类型,具体有三种类型: - ResultSet.TYPE_FORWARD_ONLY:ResultSet只能向前移动。是缺省值。 - ResultSet.TYPE_SCROLL_SENSITIVE:在修改后重新滚动到修改所在行,可以看到修改后的结果。 - ResultSet.TYPE_SCROLL_INSENSITIVE:对可修改例程所做的编辑不进行显示。 结果集从数据库中读取了数据之后,即使类型是ResultSet.TYPE_SCROLL_SENSITIVE,也不会看到由其他事务在这之后引起的改变。调用ResultSet的refreshRow()方法,可进入数据库并从其中取得当前游标所指记录的最新数据。 |
resultSetConcurrency | 表示结果集的并发,具体有两种类型: - ResultSet.CONCUR_READ_ONLY:如果不从结果集中的数据建立一个新的更新语句,不能对结果集中的数据进行更新。 - ResultSet.CONCUR_UPDATEABLE:可改变的结果集。对于可滚动的结果集,可对结果集进行适当的改变。 |
获取结果集中的数据
ResultSet对象提供了丰富的方法,以获取结果集中的数据。获取数据常用的方法如表2所示,其他方法请参考JDK官方文档。
表-2 ResultSet对象的常用方法
方法 | 说明 |
---|---|
int getInt(int columnIndex) | 按列标获取int型数据。 |
int getInt(String columnLabel) | 按列名获取int型数据。 |
String getString(int columnIndex) | 按列标获取String型数据。 |
String getString(String columnLabel) | 按列名获取String型数据。 |
Date getDate(int columnIndex) | 按列标获取Date型数据。 |
Date getDate(String columnLabel) | 按列名获取Date型数据。 |
使用游标获取结果
默认情况下,驱动程序将一次性获取查询的所有结果,当某个查询的结果集很庞大时,一次获取所有结果很不合理,因此JDBC驱动程序提供了一种基于数据库游标的ResultSet方法,只获取少量的行缓存在客户端。通过重新定位游标来获取下一批数据。
注意事项
基于游标的ResultSet不能在所有情况下使用。有许多限制会使驱动程序一次性获取整个结果集:
连接不能使用自动提交模式,因为后端会在事务结束时关闭游标,因此在自动提交模式下,事务结束后,在从游标获取数据之前,游标已经被关闭。
Statement必须使用ResultSet.TYPE_FORWARD_ONLY类型创建,这意味着不能在结果集中进行跳转或向后滚动。这也是默认值,因此不需要在代码中额外指定。
给定的查询语句必须是单条语句,不能是用分号连接在一起的多个语句。
代码示例
/* 将 Auto Commit设置为 off */
conn.setAutoCommit(false);
pstmt = conn.prepareStatement("SELECT * FROM fruit");
/* 开启游标 */
pstmt.setFetchSize(20);
rest = pstmt.executeQuery();
while (rest.next())
{
System.out.print("a row has returned.\n");
}
rest.close();
/* 关闭游标 */
pstmt.setFetchSize(0);
rest = pstmt.executeQuery();
while (rest.next())
{
System.out.print("many rows are returned.\n");
}
rest.close();
/* 关闭语句 */
pstmt.close();
在结果集中定位
ResultSet对象具有指向其当前数据行的游标。最初,游标被置于第一行之前。next方法将游标移动到下一行;因为该方法在ResultSet对象没有下一行时返回false,所以可以在while循环中使用它来迭代结果集。但对于可滚动的结果集,JDBC驱动程序提供更多的定位方法,使ResultSet指向特定的行。
表-3 在结果集中定位的方法
方法 | 说明 |
---|---|
next() | 把ResultSet向下移动一行。 |
previous() | 把ResultSet向上移动一行。 |
beforeFirst() | 把ResultSet定位到第一行之前。 |
afterLast() | 把ResultSet定位到最后一行之后。 |
first() | 把ResultSet定位到第一行。 |
last() | 把ResultSet定位到最后一行。 |
absolute(int) | 把ResultSet移动到参数指定的行数。 |
relative(int) | 通过设置为1向前(设置为1,相当于next())或者向后(设置为-1,相当于previous())移动参数指定的行。 |
获取结果集中游标的位置
对于可滚动的结果集,可能会调用定位方法来改变游标的位置。JDBC驱动程序提供了获取结果集中游标所处位置的方法。
表-4 获取结果集游标的位置
方法 | 说明 |
---|---|
isFirst() | 是否在一行。 |
isLast() | 是否在最后一行。 |
isBeforeFirst() | 是否在第一行之前。 |
isAfterLast() | 是否在最后一行之后。 |
getRow() | 获取当前在第几行。 |