32

我有一个名字列表,例如:

List<String> names = ...
names.add('charles');
...

和声明:

PreparedStatement stmt = 
  conn.prepareStatement('select * from person where name in ( ? )');

如何执行以下操作:

stmt.setParameterList(1,names);

有解决方法吗?有人可以解释为什么缺少这种方法吗?

使用:java、postgresql、jdbc3

4

8 回答 8

22

这个问题很老了,但没有人建议使用setArray

这个答案可能会有所帮助https://stackoverflow.com/a/10240302/573057

于 2012-11-07T17:38:11.387 回答
20

PreparedStatement仅通过在我所知道的列表上设置一个列表,没有干净的方法可以做到这一点。

编写代码,用适当数量的问号(与列表中的数量相同)构造​​ SQL 语句(或更好地替换单个 ? 或类似标记),然后遍历列表,为每个问号设置参数。

于 2009-08-20T10:36:57.807 回答
2

由于类型擦除,此方法丢失,List 的参数类型在运行时丢失。因此需要添加几个方法:setIntParameters, setLongParameters, setObjectParameters, 等等

于 2009-08-20T10:38:07.820 回答
1

对于 postgres 9,我使用了这种方法:

 jdbcTemplate.query(getEmployeeReport(), new PreparedStatementSetter() {
        @Override
        public void setValues(PreparedStatement ps) throws SQLException {
            ps.setTimestamp(1, new java.sql.Timestamp(from.getTime()));
            ps.setTimestamp(2, new java.sql.Timestamp(to.getTime()));
            StringBuilder ids = new StringBuilder();
            for (int i = 0; i < branchIds.length; i++) {
                ids.append(branchIds[i]);
                if (i < branchIds.length - 1) {
                    ids.append(",");
                }
            }
            // third param is inside IN clause
            // Use Types.OTHER avoid type check while executing query  
            ps.setObject(3, ids.toString(), **Types.OTHER**);
        }
    }, new PersonalReportMapper());
于 2011-05-09T22:31:45.493 回答
0

如果问题的含义是在一次调用中设置多个参数...

因为类型验证已经在更高级别定义,我认为唯一需要的是setObject(...)

因此,可以使用实用方法:

public static void addParams(PreparedStatement preparedStatement, Object... params) throws SQLException {
    for (int i = 0; i < params.length; i++) {
        Object param = params[i];
        preparedStatement.setObject(i+1, param);
    }
}

用法:

SqlUtils.addParams(preparedStatement, 1, '2', 3d);

随意将其转换为 Java 8 lambda :)

于 2016-04-10T14:05:25.840 回答
-1

今天早上我正在查看代码,我的一位同事采用了不同的方法,只需使用setString("name1','name2','name3").

注意:我跳过了开头和结尾的单引号,因为这些将由setString.

于 2012-07-24T14:08:35.780 回答
-1

在检查了不同论坛中的各种解决方案并没有找到一个好的解决方案之后,我觉得我想出的下面的 hack 是最容易遵循和编码的。但是请注意,这不使用准备好的查询,但无论如何都会完成工作:

示例:假设您有一个要在“IN”子句中传递的参数列表。只需在“IN”子句中放置一个虚拟字符串,例如,“PARAM”确实表示将代替该虚拟字符串的参数列表。

    select * from TABLE_A where ATTR IN (PARAM);

您可以将所有参数收集到 Java 代码中的单个字符串变量中。这可以按如下方式完成:

    String param1 = "X";
    String param2 = "Y";
    String param1 = param1.append(",").append(param2);

在我们的例子中,您可以将用逗号分隔的所有参数附加到单个字符串变量“param1”中。

将所有参数收集到一个字符串中后,您只需将查询中的虚拟文本(即本例中的“PARAM”)替换为参数字符串,即 param1。这是您需要做的:

    String query = query.replaceFirst("PARAM",param1); where we have the value of query as 

    query = "select * from TABLE_A where ATTR IN (PARAM)";

您现在可以使用 executeQuery() 方法执行查询。只需确保您的查询中的任何地方都没有“PARAM”一词。您可以使用特殊字符和字母的组合来代替单词“PARAM”,以确保查询中不会出现这样的单词。希望你得到解决方案。

于 2015-03-15T15:09:24.883 回答
-3

其他方法:

public void setValues(PreparedStatement ps) throws SQLException {
    // first param inside IN clause with myList values
    ps.setObject(1 , myList.toArray(), 2003); // 2003=array in java.sql.Types
}
于 2014-07-02T12:30:12.690 回答