Java PreparedStatements中的通配符

9

这是我当前的 SQL 语句:

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

它返回专辑或艺术家名称的完全匹配,但不返回其他内容。如果在语句中使用“%”,则会出现错误。

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

(我正在使用Java5和MySQL)

谢谢!


这是同一个问题的更好版本 - Alain O'Dea
1个回答

19

你将 % 放在绑定变量中。因此,你这样做

   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("[", "![");
} 

1
那么,如果绑定变量实际上包含了一个“%”字符呢? - Eric Noob
4
如果你的绑定变量中出现了百分号(%)字面量,应该使用反斜杠(%)对其进行转义。详见Java方法java.lang.String.replace()。 - Bill Karwin
@BillKarwin反斜杠并未被记录为此目的的转义字符。如果您包括**ESCAPE '!',并将%替换为!%_替换为!_,并将[替换为![**,则可以在很大程度上减轻此处的SQL注入风险。 - Alain O'Dea
@BillKarwin 我错了。OP说的是MySQL,默认情况下将转义字符设置为反斜杠,所以你是完全正确的。仍然需要明确说明以实现可移植性:Postgres和MySQL在这里达成一致,但Transact SQL文档对其默认值保持沉默。 - Alain O'Dea
1
其他替换怎么样?_被视为除了字面上的_之外的其他东西吗? - Paul Tomblin
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接