web-dev-qa-db-ja.com

Jdbi-Javaでリストパラメータをバインドする方法

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)
_

_%s_は_String.format_で置き換えられるため、Javaコードで適切な文字列を生成する必要があります。次に、すべての_%s_が置き換えられた後、jdbiのbindメソッドを使用します。他のすべてのパラメーター(_:parameterOne_または_?_)を置き換えます。

_String.format_をjdbiに置き換える方法はありますか?メソッドbind(String, Object)がありますが、デフォルトではリスト/配列を処理しません。私は この記事 を見つけました。これは、カスタムオブジェクトをバインドするための独自のファクトリを作成する方法を説明していますが、特にすでにサポートされているものに対しては、かなりの労力のように見えます。

14
Jaroslaw Pawlak

リンクした記事@BindInアノテーション。これは、リストの汎用的な実装を提供します。

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

すべての先のとがった角括弧をエスケープする必要があることに注意してください< このような \\<。 SOに関する以前の議論があります: jDBIでインクエリを行う方法?

13
ahus1

最近、かなり複雑なシナリオが機能するようになるまでにかなりの時間を費やしたので、例を追加したかっただけです。

クエリ:

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

}

注:私はdid haveを使用して、以下の依存関係も追加しています。

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

上記の例で注意すべき主なことは、コレクション変数(名前)を囲む<>ではなく、小なり演算子(<)のみをエスケープする必要があることです。

ご覧のとおり、クエリを書き込むためにsql.stgファイルを使用していません。最初は、@ UseStringTemplate3StatementLocatorを使用する場合、クエリをsql.stgファイルに書き込む必要があると誤って想定していました。しかし、どういうわけか、sql.stgファイルを機能させることができず、@ SqlQueryを使用して、最終的にDAOクラス内のクエリの記述に戻りました。

10
Saifadam Pathan