2009-11-02 12 views
12

Il mio progetto Java (JDK6) utilizza Spring e JDBCTemplate per tutti i relativi accessi al database. Abbiamo recentemente aggiornato da Spring 2.5 a Spring 3 (RC1). Il progetto non utilizza un ORM come né EJB.Programmazione Java - Spring e JDBCTemplate - Utilizzare query, queryForList o queryForRowSet?

Se ho bisogno di leggere un gruppo di record, e fare un po 'elaborazione interna con loro, sembra che ci sono diversi metodi (overload): query, queryForList e queryForRowSet

Quali dovrebbero essere i criteri da utilizzare uno invece dell'altro? Ci sono differenze di prestazioni? Migliori pratiche?

Potete consigliare alcuni riferimenti esterni per ulteriori ricerche su questo argomento?

risposta

34

Trovo che il modo standard per accedere come elenco sia tramite i metodi query() piuttosto che uno qualsiasi degli altri approcci. La differenza principale tra query e gli altri metodi consiste nel dover implementare una delle interfacce di callback (RowMapper, RowCallbackHandler o ResultSetExtractor) per gestire il set di risultati.

A RowMapper è probabilmente quello che ti ritrovi a usare la maggior parte del tempo. Viene utilizzato quando ogni riga del set di risultati corrisponde a un oggetto nel tuo elenco. Devi solo implementare un singolo metodo mapRow in cui inserisci il tipo di oggetto che va nella tua riga e lo restituisci. Spring ha anche un che può popolare gli oggetti in un elenco facendo corrispondere i nomi delle proprietà dei bean ai nomi delle colonne (NB questa classe è per comodità e non prestazioni).

A RowCallbackHandler è più utile quando è necessario che i risultati siano più di una semplice lista. Dovrai gestire tu stesso l'oggetto di ritorno utilizzando questo approccio. Di solito mi trovo ad usarlo quando ho bisogno di una struttura della mappa come tipo di ritorno (ad esempio per i dati raggruppati per una tabella ad albero o se sto creando una cache personalizzata basata sulla chiave primaria).

A ResultSetExtractor viene utilizzato quando si desidera controllare l'iterazione dei risultati. Implimenti un singolo metodo extractData che sarà il valore restituito della chiamata a query. Mi trovo solo ad usarlo se devo costruire una struttura dati personalizzata che è più complessa da costruire usando una delle altre interfacce di callback.

I metodi queryForList() sono utili in quanto non è necessario implementare questi metodi di callback. Esistono due modi per utilizzare queryForList. Il primo è se si sta interrogando una singola colonna dal database (ad esempio un elenco di stringhe) è possibile utilizzare le versioni del metodo che accetta una classe come argomento per fornire automaticamente un elenco di soli oggetti di tali classi .

Quando si chiamano le altre implementazioni di queryForList(), si otterrà una lista con ogni voce di una mappa di ogni colonna. Mentre questo è bello in quanto si risparmiano le spese di scrittura dei metodi di callback, trattare questa struttura dati è abbastanza ingombrante. Ti troverai a fare un sacco di casting poiché i valori della mappa sono di tipo Object.

Non ho mai visto i metodi queryForRowSet utilizzati in natura. Questo caricherà l'intero risultato della query in un oggetto CachedRowSet wapped da Spring SqlRowSet. Vedo un grande svantaggio nell'usare questo oggetto in quanto se passi lo SqlRowSet agli altri livelli della tua applicazione, stai accoppiando questi livelli all'implementazione di accesso ai dati.

Non dovresti notare alcuna differenza di prestazioni enorme tra nessuna di queste chiamate, ad eccezione di quanto menzionato con lo BeanPropertyRowMapper. Se stai lavorando con una complessa manipolazione di un set di risultati di grandi dimensioni, potresti ottenere alcuni miglioramenti delle prestazioni scrivendo uno ResultSetExtractor ottimizzato per il tuo caso specifico.

Per ulteriori informazioni, consultare lo Spring JDBC documentation e lo JavaDoc for the classes I've mentioned. Puoi anche dare un'occhiata ad alcuni dei libri su Spring Framework. Anche se è un po 'datato, Java Development with the Spring Framework ha una sezione molto buona su come lavorare con il framework JDBC. Soprattutto, vorrei solo provare a scrivere del codice con ciascun metodo e vedere cosa funziona meglio per te.

3

Dal momento che ci si trova nella meravigliosa terra Generics, che cosa si può davvero voglia di fare è usare SimpleJdbcTemplate e utilizzare i suoi metodi per query()Lists di oggetti e queryForObject() per singoli oggetti. Ragionare per questo è semplicemente che sono ancora più facili da usare rispetto a quelli in JdbcTemplate.

+1

AFIK il metodo di query compatibile con Java 5 è disponibile anche in JDBCTemplate nella primavera 3 – Adrian

+1

Ora che ho controllato, JdbcTemplate non utilizza Generics in Spring 2.5.6 ma è in 3.0.0. Sento odore di deprecazione in futuro ... :) – Esko

+0

SimpleJdbcTemplate ora è davvero deprecato – Helenesh

2

Una piccola aggiunta alle risposte eccellenti sopra: metodi aggiuntivi, come queryForInt, queryForLong, queryForMap, queryForObject, ecc. Potrebbero sembrare buone opzioni a volte se si sta eseguendo una query semplice e si prevede una singola riga.

Tuttavia, se è possibile ottenere 0 o 1 righe indietro, il metodo queryForList è generalmente più semplice, altrimenti è necessario rilevare IncorrectResultSizeDataAccessException. L'ho imparato nel modo più duro.

Problemi correlati