16

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

Handle handle = ...
Query<Map<String, Object>> 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?)。

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

4

2 回答 2

17

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

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

请注意,您必须<像这样转义所有尖括号\\<。之前有一个关于 SO 的讨论:How to do in-query in jDBI?

于 2015-09-12T08:46:53.317 回答
12

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

询问 :

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

什么对我有用:

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

}

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

@UseStringTemplate3StatementLocator 
<dependency>
    <groupId>org.antlr</groupId>
    <artifactId>stringtemplate</artifactId>
    <version>3.2.1</version>
</dependency>

在上面的示例中要观察的主要内容:您只需要转义小于运算符(即 < )而不是围绕集合变量(名称)的 <>。

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

于 2017-01-25T22:54:42.963 回答