Jdbi – 如何在Java中绑定list参数?

我们有一个由Jdbi( org.skife.jdbi.v2 )执行的SQL语句。 对于绑定参数,我们使用Jdbi的bind方法:

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

但是我们在列表中遇到问题,目前我们正在使用String.format 。 所以我们的查询看起来像这样:

 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) 

%sString.format替换,所以我们必须在java代码中生成一个正确的字符串。 然后在替换所有%s ,我们使用jdbi的bind方法替换所有其他参数( :parameterOne? )。

有没有办法用jdbi替换String.format ? 有一个方法bind(String, Object)但默认情况下它不处理列表/数组。 我发现这篇文章解释了如何编写我们自己的工厂来绑定自定义对象,但它看起来很费劲,特别是对于应该已经支持的东西。

您链接的文章也描述了@BindIn注释。 这为列表提供了通用的实现。

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

请注意,你必须逃脱所有尖括号<喜欢这个\\< 。 之前有一个关于SO的讨论: 如何在jDBI中进行查询?

我只是想添加一个例子,因为我最近花了相当多的时间来处理一个稍微复杂的方案:

查询:

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

什么对我有用:

 @UseStringTemplate3StatementLocator 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); ... ... } 

注意:因为我正在使用,我还必须添加以下依赖项

 @UseStringTemplate3StatementLocator  org.antlr stringtemplate 3.2.1  

在上面的例子中要注意的主要事情是:你只需要转义小于运算符(即<)而不是转义集合变量(名称)周围的<>。

正如您所看到的,我没有使用sql.stg文件来编写查询。最初我错误地认为在使用@ UseStringTemplate3StatementLocator时,我们必须在sql.stg文件中编写查询。 但是,不知怎的,我从来没有让我的sql.stg文件工作,我最终恢复使用@SqlQuery在DAO类中编写查询。