Jdbi – comment lier un paramètre de liste en Java?

Nous avons une instruction SQL qui est exécutée par Jdbi ( org.skife.jdbi.v2 ). Pour les parameters de liaison, nous utilisons la méthode bind de Jdbi:

 Handle handle = ... Query<Map> sqlQuery = handle.createQuery(query); sqlQuery.bind(...) 

Cependant, nous avons un problème avec les listes in- Ssortingng.format et nous utilisons actuellement Ssortingng.format pour cela. Donc, notre requête peut ressembler à ceci:

 SELECT DISTINCT tableOne.columnOne, tableTwo.columnTwo, tableTwo.columnThree FROM tableOne JOIN tableTwo ON tableOne.columnOne = tableTwo.columnOne WHERE tableTwo.columnTwo = :parameterOne AND tableTwo.columnThree IN (%s) 

%s est remplacé par Ssortingng.format , nous devons donc générer une chaîne appropriée en code java. Ensuite, une fois tous les %s remplacés, nous utilisons la méthode bind de jdbi pour remplacer tous les autres parameters ( :parameterOne ou ? ).

Existe-t-il un moyen de remplacer Ssortingng.format par jdbi? Il existe une méthode bind(Ssortingng, Object) mais elle ne gère pas les listes / tableaux par défaut. J’ai trouvé cet article qui explique comment écrire notre propre fabrique pour lier des objects personnalisés, mais cela demande beaucoup d’efforts, en particulier pour quelque chose qui devrait déjà être pris en charge.

L’ article que vous avez lié décrit également l’annotation @BindIn . Ceci fournit une implémentation générale pour les listes.

 @UseSsortingngTemplate3StatementLocator public class MyQuery { @SqlQuery("select id from foo where name in ()") List getIds(@BindIn("nameList") List nameList); } 

Veuillez noter que vous devrez échapper à tous les crochets pointus < comme ceci \\< . Il y a une discussion précédente sur SO: Comment faire en-requête dans jDBI?

Je voulais juste append un exemple car j’ai récemment passé beaucoup de temps à faire fonctionner un scénario légèrement plus complexe:

Requête:

 select * from sometable where id <:id and keys in () 

Ce qui a fonctionné pour moi:

 @UseSsortingngTemplate3StatementLocator public interface someDAO { .... .... // This is the method that uses BindIn @Mapper(someClassMapper.class) @SqlQuery("select something from sometable where age \\< :age and name in ()") List someMethod (@Bind("age") long age, @BindIn("names") List names); @Mapper(someClassMapper.class) @SqlQuery("select something from sometable where id = :id") List someMethod1 (@Bind("id") long id); ... ... } 

Note: Je devais aussi append la dépendance ci-dessous puisque j’utilise

 @UseSsortingngTemplate3StatementLocator  org.antlr ssortingngtemplate 3.2.1  

La principale chose à observer dans l’exemple ci-dessus: Il suffit d’échapper à l’opérateur inférieur à (c.-à-d. <) Et non au <> qui entoure la variable de collection (noms).

Comme vous pouvez le constater, je n’ai pas utilisé de fichier sql.stg pour écrire mes requêtes. Au départ, j’ai supposé à tort que lorsque @ UseSsortingngTemplate3StatementLocator était utilisé, nous devions écrire les requêtes dans le fichier sql.stg. Cependant, d’une manière ou d’une autre, mon fichier sql.stg n’a jamais fonctionné et je suis finalement revenu à l’écriture de la requête au sein de la classe DAO à l’aide de @SqlQuery.