对各种可用选项的分析,以及每个选项的优缺点,可以在Jaanne Boyarsky的JavaRanch Journal上的JDBC条目中的批处理选择语句中找到。
建议的选项包括:
- 准备 ,为每个值执行它,并在客户端联合结果。只需要一个预准备语句。缓慢而痛苦。
SELECT my_column FROM my_table WHERE search_column = ?
- 准备并执行它。每个 IN 列表的大小需要一个预准备语句。快速而明显。
SELECT my_column FROM my_table WHERE search_column IN (?,?,?)
- 准备并执行它。[或代替这些分号使用。每个 IN 列表的大小需要一个预准备语句。愚蠢的慢,严格地比,所以我不知道为什么博主甚至建议它。
SELECT my_column FROM my_table WHERE search_column = ? ; SELECT my_column FROM my_table WHERE search_column = ? ; ...
UNION ALL
WHERE search_column IN (?,?,?)
- 使用存储过程构造结果集。
- 准备N个不同大小的IN列表查询;例如,使用 2、10 和 50 个值。要搜索具有 6 个不同值的 IN 列表,请填充 size-10 查询,使其看起来像 。任何像样的服务器都会在运行查询之前优化重复值。
SELECT my_column FROM my_table WHERE search_column IN (1,2,3,4,5,6,6,6,6,6)
这些选项都不是理想的。
如果您使用的是 JDBC4 和支持 的服务器,则最佳选择是按照 Boris 的 anwser 中所述使用。x = ANY(y)
PreparedStatement.setArray
不过,似乎没有任何方法可以使用IN列表。setArray
有时SQL语句在运行时加载(例如,从属性文件加载),但需要可变数量的参数。在这种情况下,首先定义查询:
query=SELECT * FROM table t WHERE t.column IN (?)
接下来,加载查询。然后在运行之前确定参数的数量。参数计数已知后,运行:
sql = any( sql, count );
例如:
/**
* Converts a SQL statement containing exactly one IN clause to an IN clause
* using multiple comma-delimited parameters.
*
* @param sql The SQL statement string with one IN clause.
* @param params The number of parameters the SQL statement requires.
* @return The SQL statement with (?) replaced with multiple parameter
* placeholders.
*/
public static String any(String sql, final int params) {
// Create a comma-delimited list based on the number of parameters.
final StringBuilder sb = new StringBuilder(
String.join(", ", Collections.nCopies(possibleValue.size(), "?")));
// For more than 1 parameter, replace the single parameter with
// multiple parameter placeholders.
if (sb.length() > 1) {
sql = sql.replace("(?)", "(" + sb + ")");
}
// Return the modified comma-delimited list of parameters.
return sql;
}
对于不支持通过 JDBC 4 规范传递数组的某些数据库,此方法可以促进将 slow 转换为 faster 子句条件,然后可以通过调用该方法对其进行扩展。= ?
IN (?)
any