【问题标题】:Get Number of Rows returned by ResultSet in Java获取Java中ResultSet返回的行数
【发布时间】:2012-01-07 16:48:33
【问题描述】:

我使用了ResultSet,它返回一定数量的行。我的代码是这样的:

ResultSet res = getData();
if(!res.next())
{
    System.out.println("No Data Found");
}
while(res.next())
{
    // code to display the data in the table.
}

有什么方法可以检查ResultSet返回的行数吗?还是我必须自己写?

【问题讨论】:

标签: java resultset


【解决方案1】:

您可以使用do ... while 循环而不是while 循环,以便在循环执行后调用rs.next(),如下所示:

if (!rs.next()) {                            //if rs.next() returns false
                                             //then there are no rows.
    System.out.println("No records found");

}
else {
    do {
        // Get data from the current row and use it
    } while (rs.next());
}

或者当你得到它们时自己计算行数:

int count = 0;

while (rs.next()) {
    ++count;
    // Get data from the current row and use it
}

if (count == 0) {
    System.out.println("No records found");
}

【讨论】:

  • 我正在使用上面的代码,但显示记录但它丢失了第一条记录
  • 结果集中的行索引从 1 开始
  • @FranciscI.B 上面的示例中没有使用行索引,因此行索引是从 1 开始还是其他任何值都没有关系。
  • 也许@KaranRajput 正在使用它。我不知道怎么会丢失第一条记录,所以这是一个提示,以防他使用原始索引。
【解决方案2】:

res.next() 方法将指针指向下一行。在您的代码中,您使用了两次,首先是 if 条件(光标移动到第一行),然后是 while 条件(光标移动到第二行)。

因此,当您访问结果时,它从第二行开始。所以在结果中显示少一行。

你可以试试这个:

if(!res.next()){ 
    System.out.println("No Data Found");  
}
else{
    do{
       //your code
    } 
    while(res.next());
}

【讨论】:

    【解决方案3】:

    首先,您应该创建可以通过命令移动光标的Statement

    Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
    

    然后检索ResultSet,如下所示:

    ResultSet rs = stmt.executeQuery(...);
    

    将光标移动到最后一行并获取:

    if (rs.last()) {
        int rows = rs.getRow();
        // Move to beginning
        rs.beforeFirst();
        ...
    }
    

    然后 rows 变量将包含 sql 返回的行数

    【讨论】:

    • 注意:在 ojdbc 的情况下,如果您调用 rs.last,结果集将被迭代和缓存。所以这可能会导致意外的内存消耗
    【解决方案4】:

    一个简单的getRowCount 方法可以如下所示:

    private int getRowCount(ResultSet resultSet) {
        if (resultSet == null) {
            return 0;
        }
    
        try {
            resultSet.last();
            return resultSet.getRow();
        } catch (SQLException exp) {
            exp.printStackTrace();
        } finally {
            try {
                resultSet.beforeFirst();
            } catch (SQLException exp) {
                exp.printStackTrace();
            }
        }
    
        return 0;
    }
    

    请注意,此方法需要滚动敏感 resultSet,因此在创建连接时,您必须指定滚动选项。默认是FORWARD,使用这个方法会抛出异常。

    【讨论】:

    • resultSet.last();行返回布尔值,请放 if 语句。
    【解决方案5】:

    从 ResultSet 中区分 0 行或某些行的另一种方法:

    ResultSet res = getData();
    
    if(!res.isBeforeFirst()){          //res.isBeforeFirst() is true if the cursor
                                       //is before the first row.  If res contains
                                       //no rows, rs.isBeforeFirst() is false.
    
        System.out.println("0 rows");
    }
    else{
        while(res.next()){
            // code to display the rows in the table.
        }
    }
    

    如果你必须知道给定一个 ResultSet 的行数,这里有一个获取它的方法:

    public int getRows(ResultSet res){
        int totalRows = 0;
        try {
            res.last();
            totalRows = res.getRow();
            res.beforeFirst();
        } 
        catch(Exception ex)  {
            return 0;
        }
        return totalRows ;    
    }
    

    【讨论】:

      【解决方案6】:

      你可以使用res.previous()如下:

      ResulerSet res = getDate();
      if(!res.next()) {
          System.out.println("No Data Found.");
      } else {
          res.previous();
          while(res.next()) {
            //code to display the data in the table.
          }
      }
      

      【讨论】:

        【解决方案7】:

        您可以将 ResultSet 加载到 TableModel 中,然后创建一个使用该 TableModel 的 JTable,然后使用 table.getRowCount() 方法。如果要显示查询结果,无论如何都必须这样做。

        ResultSet resultSet;
        resultSet = doQuery(something, somethingelse);
        KiransTableModel myTableModel = new KiransTableModel(resultSet);
        JTable table = new JTable(KiransTableModel);
        int rowCount;
        rowCount = table.getRowCount;
        

        【讨论】:

          【解决方案8】:

          您可以使用 sql 计数并从结果集中检索答案,如下所示:

          Statment stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, 
                                               ResultSet.CONCUR_READ_ONLY);
          ResultSet ct = stmt.executeQuery("SELECT COUNT(*) FROM [table_name]");
          if(ct.next()){
             td.setTotalNumRows(ct.getInt(1));
          }
          

          我在这里计算所有内容,但您可以轻松修改 SQL 以根据条件进行计数。

          【讨论】:

          • 又好又简单的解决方案!!
          【解决方案9】:
          Statement st = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
          ResultSet rs=st.executeQuery("select * from emp where deptno=31");
          rs.last();
          System.out.println("NoOfRows: "+rs.getRow());
          

          第一行代码说我们可以在结果集中的任何地方移动(到第一行或最后一行或第一行之前,而无需从第一行开始逐行遍历,这很耗时)。第二行代码获取与我假设的查询匹配的记录(25 条记录),第三行代码将光标移动到最后一行,最后一行代码获取当前行号,在我的情况下为 25。如果没有记录,则 rs.last 返回 0 并且 getrow 将光标移动到第一行之前,因此返回负值表示 db 中没有记录

          【讨论】:

          • 您能否详细说明这可能有什么帮助?
          • @kommradHomer 第一行代码表示我们可以移动结果集中的任何位置(移动到第一行或最后一行或第一行之前,而无需从第一行开始逐行遍历,即时间采取)。第二行代码获取与我假设的查询匹配的记录(25 条记录),第三行代码将光标移动到最后一行,最后一行代码获取当前行号,在我的情况下为 25。如果没有记录,则 rs.last 返回 0 并且 getrow 将光标移动到第一行之前,因此返回负值表示 db 中没有记录。
          【解决方案10】:

          这是我的解决方案

           ResultSet rs=Statement.executeQuery("query");
          
              int rowCount=0;
          
          
              if (!rs.isBeforeFirst()) 
                {
          
                     System.out.println("No DATA" );
                  } else {
                      while (rs.next()) {
                          rowCount++; 
                      System.out.println("data1,data2,data3...etc..");
                      }
                      System.out.println(rowCount);
                      rowCount=0;
                      rs.close();
                      Statement.close();
                }
          

          【讨论】:

            【解决方案11】:
                    rs.last();
                    int rows = rs.getRow();
                    rs.beforeFirst();
            

            【讨论】:

              【解决方案12】:

              如果您的查询类似于 SELECT Count(*) FROM tranbook,请执行此操作 rs.next(); System.out.println(rs.getInt("Count(*)"));

              【讨论】:

                【解决方案13】:

                您可能认为 JDBC 是一个丰富的 API,而 ResultSet 有这么多方法,那么为什么不只是一个 getCount() 方法呢?好吧,对于许多数据库,例如Oracle、MySQL 和 SQL Server,ResultSet 是一个流式 API,这意味着它不会从数据库服务器加载(甚至可能获取)所有行。在某些情况下,通过迭代到 ResultSet 的末尾,您可能会显着增加执行时间。

                顺便说一句,如果你必须有几种方法可以做到这一点,例如通过使用 ResultSet.last() 和 ResultSet.getRow() 方法,这不是最好的方法,但如果你绝对需要它,它可以工作。

                不过,在 Java 中从 ResultSet 中获取列数很容易。 JDBC API 提供了一个 ResultSetMetaData 类,该类包含返回查询返回的列数并由 ResultSet 保存的方法。

                【讨论】:

                • 当您在最后一部分提到“JDBC API 提供了一个 ResultSetMetaData 类,该类包含返回查询返回的列数并由 resultSet 保存的方法”时,您实际上是指行数吗?通过 ResultSetMetaData 类?否则,它与问题本身无关,只会增加更多混乱。
                【解决方案14】:

                就我而言,我需要从 ResultSet 中获取总行数,如果总行数未达到 XLS 文件的限制,还需要访问 ResultSet 值。

                为此,我不得不对我的代码进行两项调整:

                1) 对象构造PreparedStatement的变化

                默认的 ResultSet 对象有一个只能向前移动的光标。因此,您只能遍历它一次,并且只能从第一行到最后一行。可以生成可滚动的 ResultSet 对象。以下代码片段说明了如何创建一个可滚动且对其他人的更新不敏感的结果集。

                PreparedStatement ps = connection.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, 
                ResultSet.CONCUR_READ_ONLY);
                

                2) 获取总行数。以下代码片段说明了如何:

                ResultSet rs = ps.executeQuery();
                rs.last();
                int totalRowsResult = rs.getRow();
                

                PS:如果查询结果的记录数过多,可能会出现Java服务器内存不足的异常:java.lang.OutOfMemoryError: Java heap space。执行rs.last()方法时会出现这个异常

                3) 再次访问 ResultSet,您不会收到消息:exhaused result set。因此,您需要使用 rs.first() 或 rs.absolute(1) 将结果集重置为顶部。以下代码片段说明了如何:

                rs.first();
                System.out.println(rs.getString(1));
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2023-03-05
                  • 2011-12-14
                  • 2020-02-06
                  • 2018-06-11
                  • 1970-01-01
                  • 1970-01-01
                  • 2014-10-10
                  相关资源
                  最近更新 更多