2009-03-13 15 views
15

Estoy haciendo una consulta para recuperar una gran cantidad de ID (enteros). En lugar de iterar millones de veces a través del ResultSet y copiar todo uno por uno en una ArrayList, ¿hay alguna forma de recuperar todo simplemente como ArrayList?¿Cómo puedo recuperar un JDBC ResultSet como ArrayList?

entiendo que ResultSet se supone que debe ser iterado porque la implementación subyacente puede ser el almacenamiento en caché cosas, pero en mi situación sólo necesito todos los ID de inmediato. Sé que puedo configurar FetchSize en un número grande, pero aún tengo que recuperar los ID uno a uno.

Aclaración: la razón por la que quiero hacer esto es el rendimiento. La creación de perfiles me muestra que hacer ResultSet.next(), ResultSet.getInt() y ArrayList.add() millones de veces lleva bastante tiempo. Me imagino que la base de datos (estoy usando H2, que está escrito en Java) probablemente tiene la matriz o lista en algún lugar de la memoria, así que estoy buscando una manera de copiarla directamente en lugar de hacerlo a través de la interfaz iterativa ResultSet. .

+1

Probablemente, ocuparse de millones de enteros lleva mucho tiempo. ¿Desea una int [] o primitiva como una lista en su lugar? Probablemente no se implementa directamente como una lista/int debido a las actualizaciones y la tabla general. –

+0

int [] o List están bien. Básicamente estoy buscando una manera de decir a la base de datos: olvídate del almacenamiento en caché/carga lenta/etc., Solo dame los datos lo más rápido que puedas :) – Deckard

+1

Hazte un perfil y ve dónde está el problema de rendimiento. (Oracle tiene métodos de matriz de columnas en su ResultSet, IIRC. No es lo que importa para H2.) –

Respuesta

6

Ponga el código en un método. Es muy simple para llamar a métodos ...

De la parte superior de mi cabeza:

public static List<Integer> readInts(
    PreparedStatement statement 
) throws SQLException { 
    ResultSet results = statement.executeQuery(); 
    try { 
     assert results.getMetaData().getColumnCount() == 1; 

     List<Integer> ints = new ArrayList<Integer>(); 
     while (results.next()) { 
      ints.add(Integer.valueOf(results.getInt(1))); 
     } 
     return ints; 
    } finally { 
     results.close(); 
    } 
} 

A continuación, sólo lo llaman como:

List<Integer> ids = readInts(myStatemnet); 

Hecho.

+2

esto no ayuda al rendimiento, todavía está pasando por los datos. Creo que solo quiere botarlo. –

+1

¿cómo lo "vaciaría" sin pasar por los datos? (El último párrafo de la pregunta no estaba en el original, por cierto.) –

17

El uso de la biblioteca Apache DbUtils puede volver fácilmente un conjunto de resultados como una lista de mapas.

public List query(String query) { 
    List result = null; 
    try { 
     QueryRunner qrun = new QueryRunner(); 
     result = (List) qrun.query(connection, query, new MapListHandler()); 
    } catch (Exception ex) { 
     ex.printStackTrace(); 
    } 
    return result; 
} 
+0

¿Esto no superará al propio JDBC? De acuerdo, parece más conveniente, pero ciertamente, ¿no es más rápido ...? –

+0

DbUtils es una biblioteca de ayuda, por lo que todavía está utilizando JDBC. Eche un vistazo a su sitio para conocer algunas de las ventajas de usar DbUtils. http://commons.apache.org/dbutils/ – Mark

+0

Entiendo, sin embargo, el OP parece haber cambiado la pregunta después de haber respondido. Estaban buscando una forma de eludir la API de JDBC, para mejorar el rendimiento ... –

5

Si su problema es pobre rendimiento, sintonizar la declaración antes de ejecutarlo con

java.sql.Statement.setFetchSize(int) 

Experimento con 100, 1000, 10000, .. Esto evitará innecesarios de ida y vuelta, que puede ser la causa de la lentitud que mencionaste

Además, ArrayList.add() puede ser lento si se debe cambiar el tamaño de la matriz interna muchas veces, ya que crea una nueva matriz y copia todos los datos a allí. Pruebe LinkedList en su lugar.

+0

Si conoce el tamaño de búsqueda que va a utilizar, también puede declarar en el constructor ArrayList el tamaño inicial de su matriz interna como la misma cantidad. –

+1

@Daddy Por lo que entendí, el autor de la pregunta estaba agregando todos los ID devueltos a una sola lista. Esto significa que su sugerencia realmente no ayuda a menos que cree una matriz con el tamaño completo del conjunto de resultados, no solo el fetchsize. – Antonio

+1

@Deckard, esta pregunta aún no tiene una respuesta aceptada. ¿Resolvió este problema? – malatesh

Cuestiones relacionadas