Java Programming-Spring et JDBCTemplate - use query, queryForList ou queryForRowSet?

mon projet Java (JDK6) utilise printemps et JDBCTemplate pour tous ses accès à la base de données. Nous sommes récemment passés du printemps 2.5 au printemps 3 (RC1). Le projet n'utilise pas d'ORM comme hibernation ni EJB.

si j'ai besoin de lire un tas d'enregistrements, et de faire un traitement interne avec eux, il semble qu'il y ait plusieurs méthodes (surchargées): query, queryForList et queryForRowSet

Ce qui devrait être le critères pour utiliser l'un au lieu de l'autre? Existe-il des écarts de performances? Pratiques exemplaires?

Pouvez-vous recommander des références externes pour la recherche sur ce sujet?

14
demandé sur Adrian 2009-11-02 14:35:44

3 réponses

je trouve que la façon standard d'accéder à la liste en tant que query() méthodes plutôt que l'une des autres approches. La principale différence entre query et l'autre méthode est que vous devrez implémenter une des interfaces de callback (soit RowMapper, RowCallbackHandler, ou ResultSetExtractor) pour gérer votre jeu de résultats.

RowMapper est probablement ce que vous vous trouverez à utiliser la plupart du temps. Il est utilisé lors de chaque ligne de résultat correspond à un objet dans votre liste. Vous vous n'avez qu'à implémenter une seule méthode mapRow où vous peuplez le type d'objet qui va dans votre rangée et le retourner. Le printemps a aussi un BeanPropertyRowMapper qui peut remplir les objets dans une liste en faisant correspondre les noms des propriétés bean aux noms des colonnes (NB cette classe est pour la commodité et non pour la performance).

RowCallbackHandler est plus utile lorsque vous avez besoin de vos résultats afin d'être plus qu'une simple liste. Vous devrez gérer vous-même l'objet de retour en utilisant cette approche. J'ai l'habitude de je me retrouve à l'utiliser lorsque j'ai besoin d'une structure de carte comme type de retour (c'est-à-dire pour des données groupées pour une table arborescente ou si je crée un cache personnalisé basé sur la clé primaire).

ResultSetExtractor est utilisé lorsque vous souhaitez contrôler l'itération des résultats. Vous implment une méthode unique extractData qui sera la valeur de retour de l'appel à query. Je ne me retrouve à utiliser cela que si je dois construire une structure de données personnalisée qui est plus complexe à construire en utilisant l'un des autres interfaces de rappel.

queryForList() les méthodes sont précieuses en ce que vous n'avez pas à implémenter ces méthodes de callback. Il y a deux façons d'utiliser queryForList. La première est que si vous n'interrogez qu'une seule colonne de la base de données (par exemple une liste de chaînes), vous pouvez utiliser les versions de la méthode qui prend une classe comme argument pour vous donner automatiquement une liste des seuls objets de ces classes.

Lors de l'appel des implémentations de queryForList() vous aurez obtenir une liste de retour avec chaque entrée est une carte de chaque colonne. Bien que ce soit agréable en ce que vous êtes sauvé la dépense de l'écriture des méthodes de rappel, le traitement de cette structure de données est assez lourd. Vous allez faire beaucoup de casting puisque les valeurs de la carte sont de type Object.

Je n'ai jamais vu le queryForRowSet méthodes utilisées dans la nature. Cela chargera tout le résultat de la requête dans un CachedRowSet objet wapped par un Ressort SqlRowSet. Je vois une grande l'inconvénient en utilisant cet objet dans que si vous passez le SqlRowSet autour des autres couches de votre application, vous couplez ces couches à votre implémentation d'accès aux données.

vous ne devriez pas voir d'énormes différences de performances entre ces appels sauf comme je l'ai mentionné avec le BeanPropertyRowMapper. Si vous travaillez avec une manipulation complexe d'un grand jeu de résultats, vous pourriez être en mesure d'obtenir des gains de performance en écrivant un pour votre cas.

si vous voulez en savoir plus, je consulterais le Spring JDBC documentation et JavaDoc pour les classes que j'ai mentionnées. Vous pouvez également jeter un coup d'oeil à quelques-uns des livres sur le cadre de ressort. Bien qu'elle soit un peu datée!--41-->Développement Java avec Spring Framework a une très bonne section sur le travail avec le cadre JDBC. Plus que tout, je dirais juste essayer d'écrire un code avec chaque méthode et voir ce qui fonctionne le mieux pour vous.

35
répondu Jason Gritman 2009-11-07 20:42:55

Puisque vous êtes dans le merveilleux Génériques de la terre, ce que vous pouvez vraiment faire est d'utiliser SimpleJdbcTemplate et utiliser ses query() méthodes pour Lists des objets et queryForObject() pour les objets individuels. Le raisonnement est simple: ils sont encore plus faciles à utiliser que ceux de JdbcTemplate.

3
répondu Esko 2009-11-02 12:12:09

un petit ajout aux excellentes réponses ci-dessus: méthodes supplémentaires, comme queryForInt, queryForLong, queryForMap, queryForObject, etc. peut sembler comme de bonnes options à certains moments si vous exécutez une requête simple et attendez une seule rangée.

cependant, si vous pouvez obtenir 0 ou 1 lignes de retour, la méthode queryForList est généralement plus facile, sinon vous devriez attraper la IncorrectResultSizeDataAccessException. J'ai appris à la dure.

2
répondu todd.pierzina 2009-11-11 22:41:51