ResultSet丢失第一个值

时间:2010-06-05 00:13:18

标签: java jsp servlets jdbc

代码似乎工作正常,但我注意到每当我查询只有一个结果的字符串时,它什么也没有返回。不知怎的,我正在跳过我想的第一个结果,但不知道为什么。

    else{
   Conn con = null;
   try {
    con = new Conn();
   } catch (Exception e) {

    e.printStackTrace();
   }
   String sql = "SELECT productname, quantityperunit, unitprice FROM products pr, categories ca WHERE pr.categoryID = ca.categoryID AND ProductName LIKE '%" + searchTerm + "%'";
   System.out.println("last try");
   try {
    searchResults = con.query(sql);

    if (searchResults.next()){
     session.setAttribute("searchResults", searchResults);
    }


   } catch (Exception e) {

    e.printStackTrace();
   } 


  }

这是显示代码:

 java.sql.ResultSet resultSet = (java.sql.ResultSet) session.getAttribute("searchResults");
    if(resultSet == null){
     out.println("Nullified");
    }
 if(resultSet!=null){
  out.println("<table border='1'>");
     out.println("<tr><th>Product Name</th><th>Quantity per Item</th><th>Price</th><th>Quantity</th><th><Add to Cart</th></tr>");
     while(resultSet.next()){      
      out.println("<tr><td>"+resultSet.getString("ProductName")+"</td></tr>");
     }
     out.println("</table>");
 }

任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:7)

根据API docs for ResultSet next

  

将光标从当前位置向前移动一行。 ResultSet光标最初位于第一行之前;第一次调用方法next使第一行成为当前行;第二个调用使第二行成为当前行,依此类推。

但在代码中,在进入while循环之前,将光标移动到第一行:

searchResults = con.query(sql);
if (searchResults.next()){
    session.setAttribute("searchResults", searchResults);
}

解决此问题的一种方法是更改​​此内容:

while(resultSet.next()) {
   out.println(""+resultSet.getString("ProductName")+""); } out.println(""); 
}

到此:

do {
   out.println(""+resultSet.getString("ProductName")+""); } out.println("");
} while(resultSet.next());

或者,如果您的JDBC驱动程序支持它,您可以在将结果集放入会话后调用beforeFirst()

searchResults = con.query(sql);
if (searchResults.next()){
    session.setAttribute("searchResults", searchResults);
    searchResults.beforeFirst();
}

无论如何,当searchResults.next()被放入会话时,由于呼叫searchResults而导致第一行丢失:

searchResults = con.query(sql);
if (searchResults.next()){
    session.setAttribute("searchResults", searchResults);
}

答案 1 :(得分:0)

我认为resultSet.next()会将光标移动到下一个结果,因此它会立即跳过while循环第一次迭代的第一个结果。

答案 2 :(得分:0)

对于那些使用Spring JDBC并看到此行为的用户,请注意ResultSetExtractor的代码如下:

/**
 * Adapter to enable use of a RowCallbackHandler inside a ResultSetExtractor.
 * <p>Uses a regular ResultSet, so we have to be careful when using it:
 * We don't use it for navigating since this could lead to unpredictable consequences.
 */
private static class RowCallbackHandlerResultSetExtractor implements ResultSetExtractor<Object> {

    private final RowCallbackHandler rch;

    public RowCallbackHandlerResultSetExtractor(RowCallbackHandler rch) {
        this.rch = rch;
    }

    @Override
    public Object extractData(ResultSet rs) throws SQLException {
        while (rs.next()) {
            this.rch.processRow(rs);
        }
        return null;
    }
}

因此,当您使用界面并提供lambda来映射行时,请不要犯与我相同的错误,并像这样再次包含while(resultSet.next())循环,否则您还会看到正在跳过第一行:

// THIS IS BAD AND WILL MAKE YOU SKIP THE FIRST RESULT
new JdbcTemplate(getDataSource()).query(sql, resultSet -> {
    while(resultSet.next()) {
        myMappingFunction();
    }
});

正确的方法是编写映射行的代码:

new JdbcTemplate(getDataSource()).query(sql, resultSet -> {
    myMappingFunction();
});