2009-11-02 25 views
12

Mi proyecto Java (JDK6) usa Spring y JDBCTemplate para todo su acceso a la base de datos. Hace poco pasamos de Spring 2.5 a Spring 3 (RC1). El proyecto no utiliza un ORM como Hibernate ni EJB.Programación Java - Spring y JDBCTemplate - ¿Utiliza query, queryForList o queryForRowSet?

Si tengo que leer un montón de discos, y hacer algo de procesamiento interno con ellos, parece que hay varios (sobrecargados) métodos: consulta, queryForList y queryForRowSet

Cuáles deben ser los criterios a utilizar uno en lugar de la otra? ¿Hay alguna diferencia de rendimiento? ¿Mejores prácticas?

¿Puede recomendar algunas referencias externas para realizar más investigaciones sobre este tema?

Respuesta

34

Me parece que la forma estándar de acceder a la lista es a través de los métodos query() en lugar de cualquiera de los otros enfoques. La principal diferencia entre query y los otros métodos es que tendrá que implementar una de las interfaces de devolución de llamada (RowMapper, RowCallbackHandler o ResultSetExtractor) para manejar su conjunto de resultados.

A RowMapper es probable que te encuentres usando la mayor parte del tiempo. Se usa cuando cada fila del conjunto de resultados corresponde a un objeto en su lista. Solo debe implementar un solo método mapRow donde rellene el tipo de objeto que se encuentra en su fila y lo devuelva. Spring también tiene un BeanPropertyRowMapper que puede completar los objetos en una lista al hacer coincidir los nombres de las propiedades del bean con los nombres de las columnas (Nota: esta clase es para mayor comodidad, no para el rendimiento).

A RowCallbackHandler es más útil cuando necesita que sus resultados sean más que una simple lista. Tendrá que administrar el objeto de retorno usted mismo está utilizando este enfoque. Normalmente me encuentro usando esto cuando necesito una estructura de mapa como mi tipo de devolución (es decir, para datos agrupados para una tabla en árbol o si estoy creando una memoria caché personalizada basada en la clave principal).

A ResultSetExtractor se utiliza cuando desea controlar la iteración de los resultados. Implementa un único método extractData que será el valor de retorno de la llamada a query. Solo me encuentro usando esto si tengo que construir alguna estructura de datos personalizada que sea más compleja de construir usando cualquiera de las otras interfaces de devolución de llamada.

Los métodos queryForList() son valiosos porque no tiene que implementar estos métodos de devolución de llamada. Hay dos formas de usar queryForList. La primera es si solo está consultando una sola columna de la base de datos (por ejemplo, una lista de cadenas) puede usar las versiones del método que toma una Clase como argumento para darle automáticamente una lista de los únicos objetos de esas clases .

Al llamar a las otras implementaciones de queryForList(), obtendrá una lista con cada entrada siendo un mapa de cada columna. Si bien esto es bueno porque te ahorras el gasto de escribir los métodos de devolución de llamada, lidiar con esta estructura de datos es bastante difícil de manejar. Te encontrarás haciendo mucho casting ya que los valores del mapa son del tipo Object.

Nunca he visto los métodos queryForRowSet utilizados en la naturaleza. Esto cargará el resultado completo de la consulta en un objeto CachedRowSet superado por un Spring SqlRowSet. Veo una gran desventaja en el uso de este objeto porque si pasa el SqlRowSet a las otras capas de su aplicación, está combinando esas capas con su implementación de acceso a datos.

No debería ver grandes diferencias de rendimiento entre estas llamadas, excepto como mencioné con el BeanPropertyRowMapper. Si está trabajando con una manipulación compleja de un gran conjunto de resultados, es posible que obtenga algunas mejoras de rendimiento al escribir un ResultSetExtractor optimizado para su caso específico.

Si quiere saber más, consultaría Spring JDBC documentation y JavaDoc for the classes I've mentioned. También puedes echar un vistazo a algunos de los libros sobre Spring Framework. Aunque está un poco anticuado, Java Development with the Spring Framework tiene una muy buena sección sobre cómo trabajar con el marco JDBC. Sobre todo, diría que simplemente intente escribir un código con cada método y vea qué funciona mejor para usted.

3

Ya que estás en la tierra maravillosa genéricos, lo que es posible que realmente quiere hacer es usar SimpleJdbcTemplate y utilizar sus métodos para query()Lists de los objetos y queryForObject() para objetos individuales. Razonando por esto simplemente es que son incluso más fáciles de usar que los que están en JdbcTemplate.

+1

AFIK el método de consulta compatible con Java 5 está disponible también en JDBCTemplate en Spring 3 – Adrian

+1

Ahora que lo he comprobado, JdbcTemplate no usa Generics en Spring 2.5.6 pero está en 3.0.0. Huelo una desaprobación en el futuro ... :) – Esko

+0

SimpleJdbcTemplate ahora está en desuso – Helenesh

2

Una pequeña adición a las excelentes respuestas anteriores: métodos adicionales, como queryForInt, queryForLong, queryForMap, queryForObject, etc. pueden parecer buenas opciones a veces si está ejecutando una consulta simple y espera una sola fila.

Sin embargo, si puede obtener 0 o 1 filas hacia atrás, el método queryForList es generalmente más fácil, de lo contrario tendría que atrapar IncorrectResultSizeDataAccessException. Aprendí eso de la manera difícil.

Cuestiones relacionadas