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)
%s
被String.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类中编写查询。