使用IN子句中的字符串列表和JDBI

时间:2017-03-09 23:26:09

标签: java postgresql dropwizard jdbi

我正在为项目使用JDBI / Dropwizard,并希望运行一些简单的查询。我有这样的查询:

private static final String GET_STUFF = "SELECT * FROM myTable WHERE state IN (:desiredState)"

我在我的方法中绑定变量,如下所示:

@Mapper(MyType.class)
@SqlQuery(GET_STUFF)
public MyType getStuff(@Bind(desiredState) List<String> states);

但是,运行时出现以下错误:

org.skife.jdbi.v2.exceptions.UnableToCreateStatementException: 
Exception while binding 'desiredState'....
Caused by: org.postgresql.util.PSQLException: Can't infer the SQL type to use for an instance of java.util.ArrayList. Use setObject() with an explicit Types value to specify the type to use.

我传递states作为String类型的ArrayList,所以我对这里发生的事情感到有些困惑。有没有人知道用JDBI做In的正确方法?

3 个答案:

答案 0 :(得分:3)

使用注释@BindIn代替@Bind。 此外,:desiredState应写为<desiredState>

答案 1 :(得分:2)

这是对我有用的(JDBI 3.1.1):

import org.jdbi.v3.sqlobject.customizer.BindList;
import org.jdbi.v3.sqlobject.statement.SqlUpdate;

public interface JdbiRoom {
    @SqlUpdate("update Room set available = 0 where id in (<roomIds>)")
    int markRoomsAsUnavailable(@BindList("roomIds") List<Long> roomIds);
}

此外,我们发现@BindIn@UseStringTemplateSqlLocator注释中不能很好地发挥作用,因此在使用命名查询时,roomIds必须作为查询参数传递(请参见https://github.com/jdbi/jdbi/issues/1131 )以获取详细信息:

markRoomsAsUnavailable(roomIds) ::= <<
    update rooms set available = 0 where id in (<roomIds>)
>>

答案 2 :(得分:0)

@SqlQuery("SELECT ... WHERE xxx in (<uids>)")

@BindIn(value = "uids", onEmpty = BindIn.EmptyHandling.VOID) List<String> ids

别忘了给你的类添加注释

@UseStringTemplate3StatementLocator