IN使用带有 实例的SQL 子句的最佳解决方法是什么java.sql.PreparedStatement,由于 SQL注入攻击安全问题,不支持多个值:一个?占位符代表一个值,而不是值列表。
IN
java.sql.PreparedStatement
?
考虑以下 SQL 语句:
SELECT my_column FROM my_table where search_column IN (?)
使用本质上是对首先 preparedStatement.setString( 1, "'A', 'B', 'C'");使用原因的解决方法的非工作尝试。?
preparedStatement.setString( 1, "'A', 'B', 'C'");
有哪些解决方法?
此处提供了对各种可用选项的分析,以及每种选项的优缺点。
建议的选项是:
SELECT my_column FROM my_table WHERE search_column = ?
SELECT my_column FROM my_table WHERE search_column 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 (?,?,?)
SELECT my_column FROM my_table WHERE search_column IN (1,2,3,4,5,6,6,6,6,6)
这些选项都不是理想的。
如果您使用 JDBC4 和支持的服务器,最好的选择是按照此处所述x =ANY(y)使用PreparedStatement.setArray
x =ANY(y)
PreparedStatement.setArray
不过,似乎没有任何方法可以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子句条件= ?转换为 fastIN (?)子句条件,然后可以通过调用该any方法进行扩展。
= ?
IN (?)
any