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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32526233/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 20:19:20  来源:igfitidea点击:

Jdbi - how to bind a list parameter in Java?

javasqljdbi

提问by Jaroslaw Pawlak

We have an SQL statement which is executed by Jdbi (org.skife.jdbi.v2). For binding parameters we use Jdbi's bindmethod:

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

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

However we have a problem with in-lists and currently we are using String.formatfor this. So our query can look like this:

但是,我们在列表中遇到了问题,目前我们正在使用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)

%sis replaced by String.formatso we have to generate a proper string in java code. Then after all %sare replaced we are using jdbi's bindmethod to replace all other parameters (:parameterOneor ?).

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

Is there a way to replace String.formatwith jdbi? There is a method bind(String, Object)but it doesn't handle lists/arrays by default. I have found this articlewhich explains how to write our own factory for binding custom objects but it looks like a lot of effort, especially for something that should be already supported.

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

回答by ahus1

The article you linkedalso descibes the @BindInannotation. This provides a general purpose implementiation for lists.

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

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

Please note that you'll have to escape all pointy brackets <like this \\<. There is a previous discusion on SO: How to do in-query in jDBI?

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

回答by Saifadam Pathan

I just wanted to add an example since I recently spent considerable time getting a slightly more complex scenario to work :

我只是想添加一个例子,因为我最近花了相当多的时间让一个稍微复杂的场景工作:

Query :

询问 :

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

What worked for me :

什么对我有用:

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

}

Note: I did haveto also add the below dependency since I am using

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

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

The main thing to observe in the above example : You only need to escape the less than operator (i.e. < ) and not the <> that surround the collection variable (names).

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

As you can see I did not use a sql.stg file to write my queries in. Initially I incorrectly assumed that when using @UseStringTemplate3StatementLocator , we have to write the queries in the sql.stg file. However, somehow I never got my sql.stg file to work and I eventually reverted back to writing the query within the DAO class using @SqlQuery.

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