2010-06-16 13 views
22

Kennt jemand eine bessere Methode, um die Anzahl der Zeilen in einem Java-Resultset aus einer MySQL-Datenbank zu erhalten? Das zurückgegebene Resultset wird nicht die Gesamtanzahl der Zeilen sein, die von der Datenbank gelesen werden, daher glaube ich nicht, dass ich die COUNT Aggregatfunktion von SQL verwenden kann.Anzahl der Zeilen in einer Java-Ergebnismenge ermitteln

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

Aufruf resultSet.last() das Ergebnis verursacht alle Datensätze auf iterieren tatsächlich über - so ist es eindeutig ineffizient. Außerdem werden alle Daten in den Speicher zwischengespeichert, auch wenn Sie sie noch nicht benötigen. Jeder Grund, warum Sie gesagt haben, dass "das Resultset zurückgegeben wird, ist nicht die Gesamtanzahl der gelesenen Zeilen aus der Datenbank"? – RonK

+0

@RonK: Warum denkst du, wird es überall wiederholen? So etwas konnte ich in der Dokumentation nicht finden. –

+0

@Ronk: Die aus der Datenbanktabelle gelesenen Daten sind nur eine Teilmenge der Daten der Tabelle und nicht alle Daten in der Tabelle. Ich bin neugierig auf die "iterating all over" obwohl. –

Antwort

18

Eine bessere Antwort besteht darin, die Anzahl der Zeilen zu vergessen, bis Sie das ResultSet erfolgreich in ein Objekt oder eine Sammlung geladen haben. Sie können die Anzahl der Zeilen mit einer dieser Optionen beibehalten.

Es ist wichtig, ResultSets (und alle SQL-Ressourcen wie Connection und Statement) im engsten möglichen Methodenbereich zu schließen. Das bedeutet, ResultSet wird nicht aus der Persistence-Schicht übergeben. Lieber die Anzahl der Zeilen mit einem Aufruf von Collection size() ermitteln.

Hören Sie auf, über Datenbanken nachzudenken und beginnen Sie in Begriffen von Objekten zu denken. Java ist eine objektorientierte Sprache.

+0

(+1) Natürlich hast du Recht. 'count()' ist vollkommen in Ordnung für mich, aber nicht in diesem Fall. Normalerweise tun wir das, um Seitenumbruch zu erreichen. –

+1

Ich finde, dass ich die Anzahl der Zeilen wissen möchte, damit ich eine ArrayList mit der passenden Größe erstellen kann. Ich meine, die amortisierten Kosten sind vernachlässigbar, aber wenn ich es beim ersten Mal richtig hinkriege, warum nicht richtig? :-) – corsiKa

9

Sie können

SELECT FOUND_ROWS() 

sofort ausgeführt werden, nachdem die Ausführung der SELECT-Anweisung, um die Zeilenanzahl zu finden.

+0

Dies ist eine interessante Antwort. Könnten Sie den Java-Code bereitstellen, der dies erreichen würde? –

2

Sie können immer SELECT COUNT() mit den gleichen genauen Bedingungen verwenden, bevor Sie die tatsächliche SELECT machen.

+1

Erfordert jedoch immer noch eine Datenbank lesen. –

+0

@Mr Morgan: Das ist perfekt für mich. Genau so machen wir eine Paginierung. Wir fragen jedoch eine bestimmte Anzahl von Zeilen in der zweiten Abfrage. Aber hier in deinem Fall ist Duffymo sehr richtig. Wenn Sie die Datenbank bereits abgefragt haben, laden Sie sie in eine Liste oder so. –

+0

Ich suche derzeit eine zweidimensionale Arraylist nach Duffymos Idee. Vorher benötigte ich die Anzahl der Zeilen, um die Größe eines zweidimensionalen String-Arrays zu berechnen. –

1

Wenn Sie Java 6 verwenden, können Sie die JDBC4ResultSet-Klasse mit der getUpdateCount-Methode verwenden, die die Anzahl der von einer SQL-Anweisung betroffenen Zeilen auch für eine Select-Anweisung zurückgibt.

Siehe unter dem Beispielcode:

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

ich, dass diese Hilfe hoffen!

+0

Dies funktioniert nicht wirklich mit MySQL. Alles, was ich bekomme, ist -1, selbst wenn es eine Reihe gibt. –

2

Hier ist meine Lösung für diese Frage (da ich die Anzahl der zurückgegebenen Datensätze zum Erstellen eines Array oder etwas ähnliches möchte): Verwenden Sie stattdessen eine Sammlung wie Vector<T>.

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; 
} 

Sauber und einfach, nein? Funktioniert für Datensätze beliebiger Größe, die zurückgegeben werden (die Größe muss nicht vorher bekannt sein), und stellt alle Methoden zur Verfügung, die List zur Verfügung stehen.

Das hat mir eine Zeit lang gut gedient, aber wenn jemand einen Fehler darin sieht, lass es mich wissen. Möchte immer meine Praxis verbessern, weißt du?

1

Sie können auch die folgende Art und Weise verwenden, um die Gesamt Datensätze in der resultSet zu erhalten:

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

Zählung ist die Summe zurückgegebenen Zeilen für die Ergebnismenge. ;)

+2

Es funktioniert nur, wenn die Ergebnismenge scrollbar ist, und es wird über den gesamten Datensatz iterieren, also nicht sehr effizient. – assylias

0

unter dem Beispielcode mit der Lösung von Lalith Siehe:

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; 
} 
Verwandte Themen