Java PreparedStatements 中的通配符

Posted

技术标签:

【中文标题】Java PreparedStatements 中的通配符【英文标题】:Wildcards in Java PreparedStatements 【发布时间】:2010-09-24 13:46:49 【问题描述】:

这是我当前的 SQL 语句:

SEARCH_ALBUMS_SQL = "SELECT * FROM albums WHERE title LIKE ? OR artist LIKE ?;";

它会返回与专辑或艺术家姓名完全匹配的内容,但不会返回任何其他内容。我不能在语句中使用“%”,否则会出错。

如何在准备好的语句中添加通配符?

(我正在使用 Java5 和 mysql

谢谢!

【问题讨论】:

这是better version of the same question。 【参考方案1】:

您将 % 放在绑定变量中。所以你做

   stmt.setString(1, "%" + likeSanitize(title) + "%");
   stmt.setString(2, "%" + likeSanitize(artist) + "%");

您应该添加 ESCAPE '!' 以允许您在输入中转义与 LIKE 相关的特殊字符。

在使用 titleartist 之前,您应该通过转义特殊字符(!%、_[) 使用如下方法:

public static String likeSanitize(String input) 
    return input
       .replace("!", "!!")
       .replace("%", "!%")
       .replace("_", "!_")
       .replace("[", "![");
 

【讨论】:

那么,如果绑定的变量实际上有一个'%'字符呢? @Eric - 那么你不需要添加它。在 setString 中而不是在其他任何地方执行它并没有什么神奇之处。 如果你的绑定变量有一个文字'%',你应该将它转义为'\%'。请参阅 Java 方法 java.lang.String.replace()。 @BillKarwin 反斜杠未记录为用于此目的的转义字符。如果您包含 ESCAPE '!' 并将 % 替换为 !%_ 替换为 !_,并且 [ 和 ![ 它应该主要减轻这里的 SQL 注入风险。 其他替代品呢? _ 是否被视为文字 _ 以外的东西?

以上是关于Java PreparedStatements 中的通配符的主要内容,如果未能解决你的问题,请参考以下文章

为 PreparedStatements 动态设置参数

如何在多线程环境中生成 PreparedStatements?

是否有更快(更简洁)的方法来为 JDBC 中的 PreparedStatements 设置许多参数?

PreparedStatements 是不是由 CQL 字符串缓存? Datastax PreparedStatement 是不是保留语句 ID?

PostgreSQL JDBC - 使用 PreparedStatements 创建表时已存在关系

FMDB使用Cached Statement功能