2010-06-16 17 views
22

¿Alguien sabe una mejor manera de obtener el número de filas en un conjunto de resultados de Java devuelto desde una base de datos MySQL? El conjunto de resultados devuelto no va a ser el número total de filas leídas de la base de datos, así que no creo que pueda usar la función de agregado COUNT de SQL.Obtener el recuento de filas en un conjunto de resultados de 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() hará que el conjunto de resultados a iterar realidad sobre todos los registros - por lo que es claramente ineficiente. Además, forzará que todos los datos se guarden en caché en la memoria, incluso si aún no los necesita. ¿Alguna razón por la que dijiste "el conjunto de resultados devuelto no va a ser el número total de filas leídas de la base de datos"? – RonK

+0

@RonK: ¿Por qué crees que se repetirá? No pude encontrar nada como esto en los documentos. –

+0

@Ronk: los datos leídos de la tabla de la base de datos serán un subconjunto de los datos de la tabla solamente en lugar de todos los datos en la tabla. Tengo curiosidad acerca de la 'repetición de todo'. –

Respuesta

18

Una mejor respuesta es olvidarse del número de filas hasta que haya cargado correctamente el ResultSet en un objeto o colección. Puede mantener la cuenta del número de filas con cualquiera de esas opciones.

Es importante cerrar los ResultSets (y todos los recursos SQL como Connection y Statement) en el alcance del método más estrecho posible. Eso significa no pasar ResultSet fuera de la capa de persistencia. Es mejor obtener el número de filas usando una llamada Collection size().

Deje de pensar en las bases de datos y comience a pensar en términos de objetos. Java es un lenguaje orientado a objetos.

+0

(+1) Por supuesto, tienes razón. 'count()' está perfectamente bien para mí, pero no en este caso. Normalmente hacemos eso para lograr la paginación. –

+1

Me encuentro queriendo saber el recuento de filas para poder hacer una 'ArrayList' de tamaño apropiado. Quiero decir, el costo amortizado es insignificante, pero si puedo hacerlo bien la primera vez, ¿por qué no está bien? :-) – corsiKa

9

Puede ejecutar

SELECT FOUND_ROWS() 

inmediatamente después de ejecutar la instrucción SELECT para encontrar el número de filas.

+0

Esta es una respuesta interesante. ¿Podrías proporcionar el código Java que lograría esto? –

2

Siempre puede usar SELECT COUNT() con las mismas condiciones exactas, antes de hacer el actual SELECT.

+1

Aún así impone una lectura de base de datos. –

+0

@Mr Morgan: Eso está perfectamente bien para mí. En realidad, hacemos algo similar para lograr la paginación. Sin embargo, pedimos número específico de filas en la segunda consulta. Pero aquí en tu caso 'duffymo' está muy bien. Cuando ya ha consultado la base de datos, ¿por qué no cargar eso en una lista o algo así? –

+0

Actualmente estoy buscando un arraylist de 2 dimensiones según la idea de duffymo. Antes, necesitaba el número de filas del conjunto de resultados para calcular el tamaño de una matriz de Cadenas bidimensional. –

1

Si está utilizando Java 6 puede utilizar la clase JDBC4ResultSet que tiene el método getUpdateCount que devuelve el número de líneas afectadas por una instrucción SQL incluso para una instrucción Select.

Véase a continuación el código de ejemplo:

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

espero que esta ayuda!

+0

Esto realmente no funciona con MySQL. Todo lo que obtengo es -1 incluso cuando hay una fila. –

2

Aquí está mi solución a esta pregunta (ya que en su mayoría quiero el número de registros devueltos para construir una matriz o algo similar): en su lugar, use una colección como 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; 
} 

Limpio y simple, ¿no? Funciona para cualquier conjunto de registros de tamaño devuelto (no es necesario conocer el tamaño de antemano) y pone a disposición todos los métodos List.

Esto me ha sido útil por un tiempo, pero si alguien ve un error en esto, por favor avíseme. Siempre quiero mejorar mis prácticas, ya sabes.

1

También puede utilizar la siguiente manera para obtener el total de registros del conjunto de resultados:

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

recuento es el total devuelto filas para el conjunto de resultados. ;)

+2

Solo funciona si el conjunto de resultados es desplazable, y se repetirá sobre todo el registro, por lo que no es muy eficiente. – assylias

0

Véase a continuación el código de ejemplo, con la solución de 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; 
} 
Cuestiones relacionadas