这是虎年我的第一篇博客,打算就最近多次遇到且踩了多个坑的判断ResultSet是否为空做一个总结整理。

约定 链接到标题

下文获取的ResultSet对象名称规定为re。

尝试一:if(re == null) 链接到标题

我们从某个案例里尝试用debugger来查看空结果集是什么样的:

img1

显然我们从图中可知这个对象是存在的,所以re不可能是null,这个尝试也就失败了。

尝试二:re.isLast()、re.isFirst()、re.isBeforeFirst() 链接到标题

我们已知re传回来有数据时游标指向的是结果集第一行的前一行,但不清楚无数据时光标的指向,所以就拿样例来测试一下吧。

ResultSet re = pstmt.executeQuery("select * from example");

if(re.isLast()){
    System.out.println("isLast is true");
}else{
    System.out.println("isLast is false");
}

if(re.isFirst()){
    System.out.println("isFirst is true");
}else{ 
    System.out.println("isFirst is false");
}

if(re.isBeforeFirst()){
    System.out.println("isBeforeFirst is true");
}else{
    System.out.println("isBeforeFirst is false");
}

返回为空时 链接到标题

isLast is false

isFirst is false

isBeforeFirst is false

返回非空时 链接到标题

isLast is false

isFirst is false

isBeforeFirst is true

结论 链接到标题

显然isLastisFirst这两个方法是不可以实现我们的需求的,但isBeforeFirst是可以的。

尝试三:re.next() 链接到标题

关于这种尝试我们也可以用与尝试二类似的方法来测试,但因为这是一个可以改变光标指向的方法,所以我单列了出来。

ResultSet re = pstmt.executeQuery("select * from example");

if(re.next()){
    System.out.println("next is true");
}else{
    System.out.println("next is false");
}

返回为空时 链接到标题

next is false

返回非空时 链接到标题

next is true

结论 链接到标题

显然next方法是可以实现需求的,但因为一旦调用了该方法就会使光标移向下一行,如果我们要先判断是否为空,若非空则读取返回数据的话,我们有以下两种策略:

策略一 链接到标题

我们在声明prepareStatement时传入参数ResultSet.TYPE_SCROLL_INSENSITIVE,且在判断是否为空后不能忘了用previous方法将光标移回第一行前。

策略二 链接到标题

在判断结果集是否为空的语句中加上为真时处理第一条记录

ResultSet re = pstmt.executeQuery("select * from example");

if(re.next()){
    System.out.println(re.getInt(1));//假设处理语句
}else{
    System.out.println("ResultSet is empty");
}

尝试四:if(rs.getRow()==0) 链接到标题

这个尝试的思想的先将光标移至结果集的最后,然后获得此时光标指向的那一行的行号:

ResultSet re = pstmt.executeQuery("select * from example");

rs.last();
if(rs.getRow()==0){
         System.out.println("ResultSet is empty");
}

实践可知这是可行的,但也有一个和尝试三一样的问题:此时的光标已经移动了。且调用last方法本身也需要在声明prepareStatement时传入参数ResultSet.TYPE_SCROLL_INSENSITIVE,最终若要读取结果集内的数据则需要调用beforeFirst方法使光标回到第一行前。