Java
SQL
ResultSet
Database Programming
Coding Tips

How do I get the size of a java.sql.ResultSet?

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

In Java, the java.sql.ResultSet interface represents a database result set obtained from executing SQL queries via Statement, PreparedStatement, or CallableStatement. Determining the size (or number of rows) directly from a ResultSet can be essential for various reasons such as pagination, data validation, or even just logging the number of records fetched. However, unlike some collections in Java, ResultSet does not provide a direct method to retrieve its size.

Understanding the ResultSet Type

Before diving into the mechanisms to determine the size, understanding the type of ResultSet is crucial. The ResultSet can be of type TYPE_FORWARD_ONLY (which only allows moving forward), TYPE_SCROLL_INSENSITIVE (which allows moving forward and backward but does not reflect changes made by others), or TYPE_SCROLL_SENSITIVE (which allows moving in any direction and reflects changes made by others). The type influences how, or even if, you can count the rows.

Techniques to Determine the Size of a ResultSet

1. Scrolling the ResultSet

If the ResultSet type allows scrolling (i.e., it is either TYPE_SCROLL_INSENSITIVE or TYPE_SCROLL_SENSITIVE), you can navigate to the last row and use the getRow() method to determine the size:

java
1public int getResultSetSize(ResultSet rs) throws SQLException {
2    int size = -1;
3    if (rs != null) {
4        rs.last();               // Move cursor to the last row
5        size = rs.getRow();      // Get row number (this is the total number of rows)
6        rs.beforeFirst();        // (Optional) Reset cursor position
7    }
8    return size;
9}

2. Querying with SQL Count

For a forward-only ResultSet or when you want to avoid the potential overhead of scrolling a large ResultSet, executing a separate SQL COUNT query can be more efficient:

java
1public int getResultSetSizeUsingCount(Connection conn, String tableName) throws SQLException {
2    int count = 0;
3    PreparedStatement ps = conn.prepareStatement("SELECT COUNT(*) FROM " + tableName);
4    ResultSet rs = ps.executeQuery();
5    if (rs.next()) {
6        count = rs.getInt(1);
7    }
8    rs.close();
9    ps.close();
10    return count;
11}

Note: This method requires knowledge of the database schema.

3. Looping Through ResultSet

For TYPE_FORWARD_ONLY result sets, if it is undesirable or impractical to rerun a count query, you might have no choice but to loop through the ResultSet:

java
1public int getResultSetSizeByLooping(ResultSet rs) throws SQLException {
2    int rowCount = 0;
3    if (rs != null) {
4        while (rs.next()) {
5            rowCount++;
6        }
7        rs.beforeFirst();  // Reset cursor if re-use of ResultSet is needed
8    }
9    return rowCount;
10}

Performance and Consequences

These techniques have different performance implications:

  • Scrolling: Efficient for smaller result sets but performance degrades as the size increases.
  • Count Query: Generally very fast but requires a separate query and correct SQL.
  • Looping: Inefficient for large datasets and consumes more time and resources.

Each method's performance and feasibility also depend on the database driver capabilities and DBMS behaviors.

Summary Table

MethodCompatibilityPerformanceUse Case
Scrolling and getRow()Scrollable ResultSetFast for small dataGeneral purpose, when scrolling is achievable
SQL COUNT queryAll ResultSet typesVaries by DB setupWhen table name/schema is known
Loop through ResultSetForward-only ResultSetSlow for large dataWhen other methods are not applicable

Conclusion

In conclusion, determining the size of a java.sql.ResultSet requires understanding both the type of ResultSet and the context in which it is used. Each method has its appropriate use case depending on the requirements and constraints of your database environment and the Java application design. While some methods may be optimal in terms of performance, they might require additional privileges or knowledge about the database schema, making them less versatile or practical in certain scenarios. In designing your approach, consider the balance between implementation complexity, performance needs, and application architecture.


Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.