Ceci est ma première expérience avec jdbCtemplates et j'ai couru dans un cas où je dois utiliser une requête qui ressemble à ceci: Comment puis-je faire ça? J'ai déjà essayé de transmettre une valeur de liste / de matrice, mais cela n'a pas fait l'affaire, je reçois une exception. Mon code actuel ressemble à ceci: p> Documentation de printemps indique qu'il n'y a aucun moyen de le faire en plus de générer le nombre requis de"? " placements pour correspondre à la taille de la liste des paramètres. Y a-t-il une solution de contournement? P> p>
4 Réponses :
Je ne pense pas que vous puissiez faire cela comme un seul '?'. Ce n'est rien à voir avec les modèles Spring JDBC, c'est Core SQL. P>
Vous devrez construire un (?,?,?) Pour autant d'entre eux que nécessaire. P>
Il y a une solution de contournement pour cela qui ne vous oblige pas à ajouter de manière dynamique "?" placements vers la requête. Voir ma réponse ci-dessous.
incroyable que c'est la réponse acceptée. Voir la réponse upvote ci-dessous.
Il y a une solution de contournement utilisant NamedParameterjdbctemplate au lieu de SimpleJDBCDaosupport , où vous pouvez faire quelque chose comme ceci: Ceci a une limitation potentiellement catastrophique concernant le nombre de paramètres que vous pouvez transmettre La liste qui dépend de la DB que vous utilisez. p> espère que c'est utile ... p> p>
Il fonctionne. La limitationcaropathique n'est pas produite dans mon projet.
@janwen La limitation concerne le nombre de paramètres que vous pouvez passer à une clause dans une clause, généralement la limite est de 1000, mais comme je l'ai dit, cela dépend de la DB. 1000 est assez élevé, donc sur la plupart des cas que vous devriez aller, c'est probablement votre cas
@Chepech est-ce que nous pouvons augmenter la limite?
Comment l'utiliser si je veux avoir une liste d'objets de classe personnalisée (avec Rowmapper) en conséquence?
@Vipin Vous le faites en deux étapes, dans la même transaction SQL (vraiment pas besoin de transaction, mais le même contexte - c'est-à-dire que vous ne fermez pas la connexion entre): faites d'abord une table temporaire et insérez vos valeurs. Ensuite, vous faites le choix avec une jointure unilatérale, par ex. joint gauche. BTW, vous devriez probablement supprimer la table TEMP dans un essai-enfin à nettoyer avant de laisser la connexion retourner dans une piscine de données ou similaire.
Pour une liste longue (ex. Oracle a une limitation de 1000 éléments) Vous pouvez simplement le séparer à plus de sélection:
List<Long> listIds = Arrays.asList(1L, 2L, ..... , 10000L); // list with ids String query = "select NOTE from NOTE where ID in (:listIds)"; List<String> noteListResult = new ArrayList<>(); int current = 0; int iter = 100; while (current < listIds.size()) { Map<String, List<Long>> noteIdsMap = Collections.singletonMap("listIds", listIds.subList(current, (current + iter > listIds.size()) ? listIds.size() : current + iter)); List<String> noteListIter = namedParameterJdbcTemplate.queryForList(query, noteIdsMap, String.class); noteListResult.addAll(noteListIter); current += iter; } return noteListResult;
Veuillez essayer avec MapSQLParameTersource avec NamedParameterjdbCtemplate.
MapSqlParameterSource parameters = new MapSqlParameterSource(); parameters.addValue("array", inputarray); NamedParameterJdbcTemplate jdbctemplate = new NamedParameterJdbcTemplate( this.jdbcTemplate.getDataSource());
La clause SQL
IN code> n'accepte pas une seule variable pour représenter une liste de valeurs - aucune base de données ne fait pas, sans utiliser SQL dynamique.
J'avais peur que ce soit le cas ... Je veux dire que choisir est aussi vieux que SQL lui-même, WTF !! Je suis dérouté, il n'y a pas de soutien pour cela.