Salut,
Tout d'abord merci pour cette belle bibliothèque.
L'erreur que je rencontre est la suivante :
Lier une liste vide
Aucune fabrique d'arguments enregistrée pour '[]' de type java.util.List
Pouvez-vous fournir plus de contexte? Quel SQL exécutez-vous ? Quel fournisseur de base de données ?
Salut @qualidafial ,
Sql : select * from invoice where invoice.id IN :ids
Fournisseur de base de données : SQL Server 2017
D'accord, ça a du sens maintenant.
JDBC est un peu bizarre lorsque vous travaillez avec des tableaux - vous devez connaître le nom du type de données utilisé par le fournisseur de la base de données. Pour aider Jdbi à connecter les points, vous devez enregistrer le nom du type d'élément de tableau par nom de classe Java :
Jdbi jdbi = Jdbi.create(...);
...
jdbi.registerArrayType(int.class, "integer");
jdbi.registerArrayType(Integer.class, "integer");
Cela dit, nous pourrions améliorer nos messages d'exception pour orienter les utilisateurs dans la bonne direction.
@qualidafial Bro, c'est du top, merci beaucoup !
:+1: Juste une mise en garde, nous pourrions ajouter un plugin SQL Server à Jdbi si vous pouvez m'indiquer de la documentation afin que je sache quels types de données personnalisés le pilote prend en charge et quels sont les mappages entre les types Java et le type de données JDBC noms.
Accord.
Types de données de base :
https://docs.microsoft.com/en-us/sql/connect/jdbc/using-basic-data-types
Types de données avancés :
https://docs.microsoft.com/en-us/sql/connect/jdbc/using-advanced-data-types
@qualidafial FYI, apparemment l'instruction IN avec un SqlArray préparé n'est pas pris en charge par le pilote JDBC SQL Server
Vous pouvez également utiliser @BindList
:
@SqlQuery("select * from invoice where invoice.id IN (<ids>)")
Set<Invoice> getInvoices(@BindList("ids") List<Integer> ids);
Sachez que différents fournisseurs de bases de données peuvent imposer des limites au nombre d'éléments autorisés dans une clause WHERE column IN (a, b, c, ...)
séparée par des virgules.
Apparemment, le serveur SQL ne prend en charge que les paramètres à valeur unique, j'ai donc créé le tableau manuellement, mais cela n'est pas sûr pour les tableaux de chaînes et peut introduire l'injection SQL.
default List<LotInvoiceRef> getInvoices(List<Long> invoiceIds) {
final List<LotInvoiceRef> lotInvoiceRefs = invoiceIds.stream()
.map(String::valueOf)
.reduce((a, b) -> a + "," + b)
.map(this::getAllInvoiceRefs)
.orElse(new ArrayList<>());
return lotInvoiceRefs;
}
@georgerb s'il vous plaît voir mon dernier commentaire, qui devrait protéger contre l'injection SQL
@qualidafial J'adore l'approche @BindList mais j'ai besoin d'un moyen d'autoriser les listes vides pour le paramètre que @BindList interdit explicitement.
@qualidafial nvm, Une fouille rapide dans l'annotation et j'ai utilisé ceci: @BindList(value = "invoiceIds", onEmpty = BindList.EmptyHandling.NULL)
et cela a parfaitement fonctionné
Encore une fois, c'est top. Y a-t-il un moyen de contribuer? au moins vous aider avec la documentation.
Merci, vous êtes très gentil. Nous :heart: pull requests !
De cette seule conversation, je déduis trois améliorations possibles :
@BindList
(et peut-être @DefineList
pendant que nous y sommes).Si vous auriez l'amabilité de soumettre un numéro distinct ciblé sur chacun des éléments ci-dessus. Ensuite, nous pouvons fermer celui-ci et suivre chacun de manière isolée.
Et si vous avez une idée pour améliorer Jdbi que vous aimeriez utiliser, n'hésitez pas ! Les plugins JPA, Kotlin et Vavr, ainsi que de nombreux éléments de Core et SQL Object étaient tous des soumissions d'utilisateurs de Jdbi.
@qualidafial terminé. #993
Merci! Clôture de ce numéro en faveur du #993
Commentaire le plus utile
D'accord, ça a du sens maintenant.
JDBC est un peu bizarre lorsque vous travaillez avec des tableaux - vous devez connaître le nom du type de données utilisé par le fournisseur de la base de données. Pour aider Jdbi à connecter les points, vous devez enregistrer le nom du type d'élément de tableau par nom de classe Java :