//程序片断1 void func() { ....... ResultSet rs = stmt.executeQuery (sql); if ( rs.next () )//表明找到记录 { ...... try { bs.setId (rs.getInt ("id")); } catch (SQLException ex) { ex.printStackTrace(); } try { bs.setStrAddress (rs.getString ("address")); } catch (SQLException ex1) { ex1.printStackTrace(); } ..... } .......... }
因为 “//程序片断1”中的if语句太长,我将其抽取为一个独立的函数,如下://程序片断2 void func() { ....... ResultSet rs = stmt.executeQuery (sql); setBohaoStudentField(bs,rs); .......... } //程序片断3 private void setBohaoStudentField (final BohaoStudentMenber bs, final ResultSet rs) throws SQLException { if ( rs.next () )//表明找到记录 { ...... try { bs.setId (rs.getInt ("id")); } catch (SQLException ex) { ex.printStackTrace(); } try { bs.setStrAddress (rs.getString ("address")); } catch (SQLException ex1) { ex1.printStackTrace(); } ..... } }
这样本没有错误,而且使得程序逻辑更清晰了。好的下面我们继续向后看。在后面的某个时候,我需要对rs.next()为空的情况进行处理,好的我自然想到按如下方式进行:
//程序片断4 void func() { ....... ResultSet rs = stmt.executeQuery (sql); if ( rs.next () )//表明找到记录 { setBohaoStudentField(bs,rs); }else { .... } .......... } //程序片断5 private void setBohaoStudentField (final BohaoStudentMenber bs, final ResultSet rs) throws SQLException { if ( rs.next () )//表明找到记录 { ...... try { bs.setId (rs.getInt ("id")); } catch (SQLException ex) { ex.printStackTrace(); } try { bs.setStrAddress (rs.getString ("address")); } catch (SQLException ex1) { ex1.printStackTrace(); } ..... } }
这样做了之后,程序出现了错误,我不知道错在哪里,但是我知道在我这样改了之后,程序就出错了,好的,我就在我更改的地方进行断点跟踪,最后发现是“//程序片断4” 和“//程序片断5”的调用出现错误了,为什么呢?我并没有更改他们的调用方式阿,为什么错误了呢?为什么在“//程序片断4”中的if ( rs.next () ) 判断为真,但是在“//程序片断5”中的if ( rs.next () ) 判断为假了呢?查看帮助文档,发现 ResultSet.next() 的说明是这样的:boolean next() Moves the cursor down one row from its current position.我突然意识到我犯了一个致命的错误,在我调用 setBohaoStudentField(bs,rs);函数之前,我作了一次 if ( rs.next () )判断,之后在 setBohaoStudentField函数体内部我又再次做了一次 if ( rs.next () )判断,到这里就明白了,这个时候的判断,记录集 rs 的游标已经因为在调用之前的那次判断而向下移动了一个,也就是说当前的记录改变了,这就是所有的症结所在.这真是让人很郁闷的事情啊,还好,我及时发现了,要是等到后面的某个时候去调试,那还不知道要跟踪到什么时候呢!!