gpt4 book ai didi

java - PreparedStatement IN 子句替代方案?

转载 作者:行者123 更新时间:2023-11-29 20:35:45 28 4
gpt4 key购买 nike

使用 SQL 的最佳解决方法是什么 IN具有 java.sql.PreparedStatement 实例的子句,由于 SQL 注入(inject)攻击安全问题,不支持多个值:1 ?占位符代表一个值,而不是一组值。

考虑以下 SQL 语句:

SELECT my_column FROM my_table where search_column IN (?)

使用preparedStatement.setString( 1, "'A', 'B', 'C'" );本质上是对使用?原因的解决方法的非工作尝试。首先。

有哪些可用的解决方法?

最佳答案

Jeanne Boyarsky 的 Batching Select Statements in JDBC 中提供了对各种可用选项及其优缺点的分析。 JavaRanch Journal 上的条目。

建议的选项是:

  • 准备SELECT my_column FROM my_table WHERE search_column = ? ,对每个值执行它并在客户端对结果进行 UNION。仅需要一份准备好的声明。缓慢而痛苦。
  • 准备SELECT my_column FROM my_table WHERE search_column IN (?,?,?)并执行它。每个 size-of-IN-list 需要一个准备好的语句。快速且明显。
  • 准备SELECT my_column FROM my_table WHERE search_column = ? ; SELECT my_column FROM my_table WHERE search_column = ? ; ...并执行它。 [或使用UNION ALL代替那些分号。 --ed] 每个 size-of-IN-list 需要一个准备好的语句。慢得愚蠢,严格来说比 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 和支持 x = ANY(y) 的服务器,这是最佳选择,就是使用PreparedStatement.setArrayBoris's anwser 中所述.

似乎没有办法制作setArray不过,可以使用 IN 列表。

<小时/>

有时 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 规范传递数组的数据库,此方法可以帮助转换缓慢的 = ?进得更快IN (?)子句条件,然后可以通过调用 any 来扩展该条件方法。

关于java - PreparedStatement IN 子句替代方案?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38812580/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com