通过 ResultSet 的 next() 方法避免跳过一行

Avoiding skipping a row By next() Method of ResultSet

这是一个简单的代码,用于打印数据库中的一些行。但是当我执行此操作时,屏幕上不会打印任何内容。我认为问题是 rs.next() 方法跳过了一行。那么我怎样才能避免这种情况或重置 rs.next() 方法的位置呢?

 String searchword = Searchtf.getText();
 try {
        Class.forName("com.mysql.jdbc.Driver");

        java.sql.Connection con = DriverManager.getConnection(url, db_username, db_password);

        java.sql.Statement stat = con.createStatement();

        String searchQuery = "SELECT * FROM user WHERE Name LIKE '" + searchword + "' ";

java.sql.ResultSet rs = stat.executeQuery(searchQuery);

        if (rs.next()) {
            while (rs.next()) {
                System.out.print(rs.getString("idUser") + " ,");
                System.out.print(rs.getString("Name") + " ,");
                System.out.print(rs.getString("Email") + " ,");
                System.out.println(rs.getString("country") + " .");
            }
        } else {
            JOptionPane.showMessageDialog(null, "Not Found");
        }
  } catch (Exception ex) {
        ex.printStackTrace();
    }

首先,停止那样构建 SQL - 使用参数化 SQL 和 PreparedStatement。您当前的代码容易受到 SQL 注入攻击。

基本上,不要连续两次调用 rs.next()(首先在 if 中,然后在 while 中)...您可以通过转换您的 while 循环进入 do/while 循环:

if (rs.next()) {
    do {
        System.out.print(rs.getString("idUser") + " ,");
        System.out.print(rs.getString("Name") + " ,");
        System.out.print(rs.getString("Email") + " ,");
        System.out.println(rs.getString("country") + " .");
    } while (rs.next());
}

只是while循环,用一个单独的变量来检测你已经看到一些结果:

bool anyResults = false;
while (rs.next()) {
    anyResults = true;
    System.out.print(rs.getString("idUser") + " ,");
    System.out.print(rs.getString("Name") + " ,");
    System.out.print(rs.getString("Email") + " ,");
    System.out.println(rs.getString("country") + " .");
}
if (!anyResults) {
    JOptionPane.showMessageDialog(null, "Not Found");
}

(此外,您应该使用 try-with-resources 来关闭您的 ResultSet 等,并且仅将堆栈跟踪打印到标准输出几乎从来都不是处理异常的合适方法...)

不需要不用:

 if (rs.next()) {

while 够了,这使结果翻了一番。 相反,您可以使用 :

boolean b = false;
while (rs.next()) {
   b = true;
   ...
}

if(!b) {
  JOptionPane.showMessageDialog(null, "Not Found");
}

您必须改用 PreparedStatement,以避免任何 SQL 注入或语法错误。

嘿,它正在跳过行,因为您在 if 子句中执行 rs.next(),然后在 while 中再次执行。所以 while 正在做的第一次迭代实际上是第二行。最好的选择是在 if 子句中,你应该写 if(rs.first())

rs.next() 将在 if 中递增游标,因此如果结果集只有查询返回的一行,则 while 将再次移动游标并且不会获得任何数据 print.Use do..while 改为循环。

if (rs.next()) {
            do {
                System.out.print(rs.getString("idUser") + " ,");
                System.out.print(rs.getString("Name") + " ,");
                System.out.print(rs.getString("Email") + " ,");
                System.out.println(rs.getString("country") + " .");
            }while (rs.next());
        } 

感谢您的每一个回答。我发现放置 rs.relative(-1) 也可以完成这项工作。但是上面的答案编码得很好并且比我的更好。所以谢谢大家。我是编程新手,我会在编码时考虑您的所有建议。谢谢

if (rs.next()) {
     rs.relative(-1);
        while (rs.next()) {
            System.out.print(rs.getString("idUser") + " ,");
            System.out.print(rs.getString("Name") + " ,");
            System.out.print(rs.getString("Email") + " ,");
            System.out.println(rs.getString("country") + " .");
        }
 }

The API docs for ResultSet 解释一下 next() 方法:

Moves the cursor forward one row from its current position. A ResultSet cursor is initially positioned before the first row; the first call to the method next makes the first row the current row; the second call makes the second row the current row, and so on.

每次调用 next() 方法时,都会将光标移动到下一行。 这发生在您的代码中(两次):

if (rs.next()) {
            while (rs.next()) { 

避免该问题的一种方法是使用 beforeFirst() 方法。 According to the API:

Moves the cursor to the front of this ResultSet object, just before the first row. This method has no effect if the result set contains no rows.

然后,每次你在代码中的某处使用 "rs.next()" 时,你都会将光标移动一个位置(到下一行)但是如果在多次使用 rs.next() 之后你需要开始从第一行读取,您可以简单地使用 rs.beforeFirst() ,当您下次调用 rs.next() 时,游标将从结果集的开头开始。

此外,您不需要在代码中使用 if 语句:

if (rs.next()) {

因为你用的时候够用了