如何使用arraylist作为准备好的语句参数[重复]

Posted

技术标签:

【中文标题】如何使用arraylist作为准备好的语句参数[重复]【英文标题】:How to use an arraylist as a prepared statement parameter [duplicate] 【发布时间】:2013-07-24 09:54:44 【问题描述】:

我已经查看并且无法找到解决我遇到的以下挑战的答案。它 看起来很简单,但我一直无法解决它。

我有一个ArrayList 类型为Long -> ArrayList<Long> 的记录ID。我想用 此记录 ID 列表用于从另一个表中选择行。到目前为止,一切都很好。现在上 挑战……

a) 我正在使用准备好的语句从使用ArrayList 作为输入的表中选择数据 为了这。

selectPS = dbConnection.prepareStatement("select columnA from tableA where id in ?");

关于上面的问题 - 应该如何定义参数?以上似乎不正确 ArrayList 类型参数。

b) 在为准备好的参数设置值时,我也遇到了问题 陈述。没有设置 ArrayList 类型值的方法,我看不到其他可行的方法 选项。

---> selectPS.set?????(1, arraylistParameter);
     ResultSet rs = selectPS.executeQuery(); 

非常感谢您为我提供的任何帮助或指导。

谢谢。

【问题讨论】:

你可以尝试传递一个数组吗?,PreparedStatement#setArray()?您需要先使用Connection#createArrayOf() 创建一个数组。列出了某些方式here。 我会为数组中的每个元素动态创建一个带有? 的字符串,使用每个值调用setLong 方法,每次递增索引。 @Thomas Grady CBIP 你的数据库是什么?如果是Oracle,则在IN 子句中将不支持超过1000 条记录。您必须编写INNER JOIN 子句更多信息-***.com/questions/4722220/… @Prabhaker... 我们正在使用 mysql。也就是说,挑战不是 sql,而是正确设置我准备好的语句以使用数组列表。感谢您转发信息。 大家好。我接受了通过 arraylist 循环并为每个调用设置 Long 参数的建议,我有我需要的东西。虽然这个选项似乎有更多的开销,但读取的行数是几千,这是为了解决生产问题。 【参考方案1】:

为什么要让生活变得艰难-

PreparedStatement pstmt = conn.prepareStatement("select * from employee where id in ("+ StringUtils.join(arraylistParameter.iterator(),",") +)");

【讨论】:

因为SQL注入【参考方案2】:

@JulienD 最好的方法是将上述过程分为两个步骤。

第 1 步: 让我们说“rawList”作为您要作为参数添加到准备好的语句中的列表。

创建另一个列表:

ArrayList<String> listWithQuotes = new ArrayList<String>();

for(String element : rawList)
    listWithQuotes.add("'"+element+"'");

第 2 步: 用逗号分隔“listWithQuotes”。

String finalString = StringUtils.join(listWithQuotes.iterator(),",");

'finalString' 将是字符串参数,每个元素用单引号和逗号分隔。

【讨论】:

这是个坏主意,因为它会让你面临 SQL 注入。【参考方案3】:

如果你有 ArrayList 然后转换成 Array[Object]

ArrayList<String> list = new ArrayList<String>();
PreparedStatement pstmt = 
            conn.prepareStatement("select * from employee where id in (?)");
Array array = conn.createArrayOf("VARCHAR", list.toArray());
pstmt.setArray(1, array);
ResultSet rs = pstmt.executeQuery();

【讨论】:

有人可以确认这是否有效吗?我收到一个错误 java.lang.AbstractMethodError: oracle.jdbc.driver.T4CConnection.createArrayOf【参考方案4】:

您可能想要使用下面的 javadoc 中提到的 setArray 方法:

http://docs.oracle.com/javase/6/docs/api/java/sql/PreparedStatement.html#setArray(int, java.sql.Array)

示例代码:

PreparedStatement pstmt = 
                conn.prepareStatement("select * from employee where id in (?)");
Array array = conn.createArrayOf("VARCHAR", new Object[]"1", "2","3");
pstmt.setArray(1, array);
ResultSet rs = pstmt.executeQuery();

【讨论】:

@Yogendra... 我调查了你的建议,但无法让它与 Long 一起使用。一旦我解决了手头的生产问题,我将进一步研究这个建议。谢谢。 就使用数组的建议回复您(和 TNI)。不幸的是,由于我们将 MySQL 作为我们的数据库,我无法使用它。 MySQL 不支持 sql 数组。这太糟糕了,因为这也可以满足我的需求。感谢您的帮助。 以上评论;还没有解决我收到错误的原因,但使用 SELECT * FROM employee WHERE id = ANY (?) 确实有效(对我来说)。 这不适用于 Oracle 数据库,因为 createArrayOf 未实现 在 Informix 中也不能工作,也是因为 createArrayOf 没有实现

以上是关于如何使用arraylist作为准备好的语句参数[重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Java 中使用准备好的语句进行选择查询?

如何使用准备好的语句动态绑定参数?

如何使用 jdbc 准备好的语句传递可变数量的参数?

如何使用准备好的 PDO 语句设置 ORDER BY 参数?

如何使用准备好的 PDO 语句设置 ORDER BY 参数?

如何在另一个准备好的语句中使用 PreparedStatement 作为子查询