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

Jar*_*lak 14 java sql jdbi

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

Handle handle = ...
Query<Map<String, Object>> sqlQuery = handle.createQuery(query);
sqlQuery.bind(...)
Run Code Online (Sandbox Code Playgroud)

但是我们在列表中存在问题,目前我们正在使用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)
Run Code Online (Sandbox Code Playgroud)

%s被替换为,String.format所以我们必须在java代码中生成一个合适的字符串.然后在%s更换之后我们使用jdbi的bind方法来替换所有其他参数(:parameterOne?).

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

ahu*_*us1 13

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

@UseStringTemplate3StatementLocator
public class MyQuery {
  @SqlQuery("select id from foo where name in (<nameList>)")
  List<Integer> getIds(@BindIn("nameList") List<String> nameList);
}
Run Code Online (Sandbox Code Playgroud)

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


小智 10

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

查询:

select * from sometable where id <:id and keys in (<keys>)
Run Code Online (Sandbox Code Playgroud)

什么对我有用:

@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 (<names>)")
    List<someclass> someMethod (@Bind("age") long age, @BindIn("names") List<string> names);

    @Mapper(someClassMapper.class)
    @SqlQuery("select something from sometable where id = :id")
    List<someclass> someMethod1 (@Bind("id") long id);
    ...
    ...

}
Run Code Online (Sandbox Code Playgroud)

注:我也有,因为我使用也增加了下面的依赖

@UseStringTemplate3StatementLocator 
<dependency>
    <groupId>org.antlr</groupId>
    <artifactId>stringtemplate</artifactId>
    <version>3.2.1</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

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

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