2010-06-16 51 views
22

Có ai biết cách tốt hơn để lấy số hàng trong một kết quả Java trả về từ cơ sở dữ liệu MySQL không? Kết quả trả về sẽ không phải là tổng số hàng được đọc từ cơ sở dữ liệu vì vậy tôi không nghĩ rằng tôi có thể sử dụng hàm tổng hợp của COUNT của SQL.Lấy số lượng hàng trong một kết quả Java

public static int getResultSetRowCount(ResultSet resultSet) { 
    int size = 0; 
    try { 
     resultSet.last(); 
     size = resultSet.getRow(); 
     resultSet.beforeFirst(); 
    } 
    catch(Exception ex) { 
     return 0; 
    } 
    return size; 
} 
+2

Calling resultSet.last() sẽ gây ra kết quả thiết lập để thực sự lặp qua tất cả các hồ sơ - vì vậy nó rõ ràng là không hiệu quả. Ngoài ra nó sẽ buộc tất cả dữ liệu được lưu vào bộ nhớ ngay cả khi bạn không cần nó. Bất kỳ lý do nào tại sao bạn nói "anh ấy trả về kết quả sẽ không phải là tổng số hàng được đọc từ cơ sở dữ liệu"? – RonK

+0

@RonK: Tại sao bạn nghĩ rằng nó sẽ được lặp lại trên tất cả? Tôi không thể tìm thấy bất cứ điều gì như thế này trong tài liệu. –

+0

@Ronk: Dữ liệu được đọc từ bảng cơ sở dữ liệu sẽ là một tập con của dữ liệu của bảng chỉ thay vì tất cả dữ liệu trong bảng. Tôi tò mò về việc 'lặp lại tất cả' mặc dù. –

Trả lời

18

Câu trả lời hay hơn là quên số hàng cho đến khi bạn tải thành công ResultSet vào một đối tượng hoặc bộ sưu tập. Bạn có thể giữ số lượng hàng với một trong các tùy chọn đó.

Điều quan trọng là đóng ResultSets (và tất cả các tài nguyên SQL như Connection and Statement) trong phạm vi phương thức hẹp nhất có thể. Điều đó có nghĩa là không chuyển ResultSet ra khỏi lớp persistence. Tốt hơn là lấy số hàng bằng cách sử dụng lệnh gọi Collection size().

Ngừng suy nghĩ về cơ sở dữ liệu và bắt đầu suy nghĩ về mặt đối tượng. Java là ngôn ngữ hướng đối tượng.

+0

(+1) Tất nhiên, bạn đã đúng. 'count()' là hoàn toàn tốt cho tôi, nhưng không phải trong trường hợp này. Chúng tôi thường làm điều đó để đạt được điều ước pagination. –

+1

Tôi thấy mình muốn biết rowcount vì vậy tôi có thể làm cho một kích thước thích hợp 'ArrayList'. Ý tôi là, chi phí khấu hao là không đáng kể, nhưng nếu tôi có thể lấy nó ngay lần đầu tiên, tại sao không đúng? :-) – corsiKa

9

Bạn có thể thực hiện

SELECT FOUND_ROWS() 

ngay sau khi thực hiện câu lệnh SELECT của bạn để tìm số liên tiếp.

+0

Đây là một câu trả lời thú vị. Bạn có thể cung cấp mã java có thể thực hiện được điều này không? –

2

Bạn luôn có thể sử dụng SELECT COUNT() với cùng điều kiện chính xác, trước khi thực hiện SELECT thực tế.

+1

Nó vẫn áp đặt một cơ sở dữ liệu đọc mặc dù. –

+0

@ Morgan Morgan: Thats hoàn toàn tốt cho tôi. Trên thực tế, chúng tôi làm điều tương tự để đạt được phân trang. Tuy nhiên, chúng tôi yêu cầu số lượng hàng cụ thể trong truy vấn thứ 2. Nhưng ở đây trong trường hợp của bạn 'duffymo' là rất đúng. Khi bạn đã truy vấn cơ sở dữ liệu, tại sao không tải nó vào một danh sách hoặc một cái gì đó. –

+0

Tôi hiện đang xem danh sách mảng 2 chiều theo ý tưởng của duffymo. Trước đây, tôi cần số lượng kết quả của các hàng để làm việc ra kích thước của một mảng chuỗi 2 chiều. –

1

Nếu bạn đang sử dụng Java 6, bạn có thể sử dụng lớp JDBC4ResultSet có phương thức getUpdateCount trả về số dòng bị ảnh hưởng bởi một câu lệnh SQL ngay cả đối với một câu lệnh Select.

Xem dưới mã ví dụ:

PreparedStatement ps = con.prepareStatement("select * from any_table ..."); 
JDBC4ResultSet rs = (JDBC4ResultSet)ps.executeQuery(); 
int rowNumber = rs.getUpdateCount(); 

Tôi hy vọng rằng điều này giúp đỡ!

+0

Điều này không thực sự làm việc với MySQL. Tất cả tôi nhận được là -1 ngay cả khi có một hàng. –

2

Đây là giải pháp của tôi cho câu hỏi này (vì tôi chủ yếu muốn số lượng bản ghi được trả lại để tạo mảng hoặc tương tự): Sử dụng bộ sưu tập như Vector<T> để thay thế.

public Vector<T> getRecords(){ 
    Vector<T> records = new Vector<T>(); 
    init_conn_and_stmt_and_rs(); 

    try { 
     rs = stmt.executeQuery("SELECT * FROM `table` WHERE `something` = 0"); 
     while(rs.next()){ 
     // Load the Vector here. 
     } 
    } catch (SQLException e) { 
     e.printStackTrace(); 
    }finally{ 
     close_rs_and_stmt_and_conn(); 
    } 
    return records; 
} 

Sạch sẽ và đơn giản, phải không? Làm việc cho bất kỳ bộ hồ sơ kích thước nào được trả lại (không cần phải biết kích thước trước khi bàn tay) và làm cho tất cả các phương thức List có sẵn.

Điều này đã phục vụ tôi tốt trong một thời gian, nhưng nếu ai đó nhìn thấy một lỗ hổng trong này, xin vui lòng cho tôi biết. Luôn luôn muốn làm cho thực hành của tôi tốt hơn, ya biết.

1

Bạn cũng có thể sử dụng cách sau để có được tổng số hồ sơ trong ResultSet:

statement = connect.createStatement(); 
resultSet = statement.executeQuery(sqlStatement); 
resultSet.last(); 
int count = resultSet.getRow(); 
System.out.println(count); 

đếm là tổng số trở lại hàng cho tập kết quả của bạn. ;)

+2

Nó chỉ hoạt động nếu resultset có thể cuộn được, và nó sẽ lặp qua tất cả các bản ghi để không hiệu quả lắm. – assylias

0

Xem bên dưới đoạn code ví dụ với các giải pháp của Lalith:

public static int getResultSetRowCount(connection) { 
    int size = 0; 
    statement = connection.createStatement(); 
    try { 
     resultSet = statement.executeQuery("SELECT FOUND_ROWS()") 
     resultSet.next() 
     size = resultSet.getInt(1) 
    } 
    catch(Exception ex) { 
     return 0; 
    } 
    statement.close(); 
    return size; 
} 
Các vấn đề liên quan