【问题标题】:Jdbi - how to bind a list parameter in Java?Jdbi - 如何在 Java 中绑定列表参数?
【发布时间】:2015-09-11 14:46:57
【问题描述】:

我们有一个由 Jdbi (org.skife.jdbi.v2) 执行的 SQL 语句。对于绑定参数我们使用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)

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

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

【问题讨论】:

    标签: java sql jdbi


    【解决方案1】:

    article you linked 也描述了@BindIn 注释。这为列表提供了通用实现。

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

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

    【讨论】:

    • 这对我有用,但如果我在同一个查询中同时使用 BindIn 和 Bind,它似乎不起作用。你也遇到这种情况?
    • @Pablote 请为此创建一个新的 StackOverflow 问题。
    • 这很酷。但是,如果我想在进行比较之前对列表中的每个项目应用lower 函数怎么办。我试过lower(name) in (lower(&lt;nameList&gt;))。这当然行不通。有什么想法吗?
    【解决方案2】:

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

    查询:

    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 类中编写查询。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-30
      • 2021-10-26
      • 1970-01-01
      • 2016-10-10
      • 1970-01-01
      • 2011-09-18
      • 2021-08-23
      • 1970-01-01
      相关资源
      最近更新 更多