不使用setString的Java SQL Escape

时间:2011-07-13 14:32:54

标签: java sql string escaping

是否有内置方法来转义SQL的字符串?我会使用setString,但它发生了我在同一个组合的SQL语句中多次使用setString,如果转义只发生一次而不是每次我说setString,那将是更好的性能(我认为)。如果我在变量中有转义字符串,我可以重复使用它。

在Java中没有办法做到这一点吗?

目前的方法,多源搜索。实际上,它们在包括连接在内的语句中完全不同,但是对于这个例子,我将只显示每个表的相同位置。

String q = '%' + request.getParameter("search") + '%';
PreparedStatement s = s("SELECT a,b,c FROM table1 where a = ? UNION select a,b,c from table2 where a = ? UNION select a,b,c FROM table3 where a = ?");
s.setString(1, q);
s.setString(2, q);
s.setString(3, q);
ResultSet r = s.executeQuery();

我知道这不是什么大不了的事,但我喜欢提高效率,而且有些情况下使用" + quote(s) + "代替?更具可读性,然后在某处找到setString

4 个答案:

答案 0 :(得分:5)

如果对参数使用setString(例如PreparedStatement.setString),则可能不需要实际的转义 - 数据可能会与SQL本身分开传递,方式如下:不需要逃避。

您是否有任何具体迹象表明这 是性能瓶颈?在数据库查询中,似乎不太可能在本地设置参数......

答案 1 :(得分:4)

简短的回答:我不会打扰。最好在最后一刻消失。当您尝试提前转义字符串并将其保留时,验证所有字符串是否已完全转义一次变得更加困难。 (两次转义字符串几乎和完全没有转义一样糟糕!)我看到很多程序试图提前逃避字符串然后遇到麻烦,因为他们需要更新字符串然后程序员忘记重新做转义,或者他们更新字符串的转义版本,或者他们有四个字符串,他们逃脱其中三个,等等。(我只是在编写程序员早期在字符串上进行HTML转义的bug,然后决定他必须截断字符串以适合表单,并最终尝试输出以“& am”结尾的字符串。也就是说,他截断了他的转义序列,因此它不再有效。)

转义字符串的CPU时间应该是微不足道的。除非你有大量的记录或重复使用的大字符串,否则我怀疑节省的费用值得担心。你可能最好花时间优化查询:保存读取一条记录可能比通过字符串转义逻辑消除1000次旅行更有价值。

更长的答案:没有内置功能。你可以轻松地编写一个:大多数SQL都只需要你加倍任何一个引号。您可能还需要加倍反斜杠或一个或两个其他特殊字符。事实上,SQL引擎之间可能有所不同,这是使用PreparedStatements并让JDBC担心它的重要参数之一。 (我个人认为应该有一个JDbC函数来进行转义,然后可以知道特定于数据库引擎的任何要求。但事实并非如此。)

无论如何,目前还不清楚它如何与PreparedStatement一起使用。必须有一些方法告诉PreparedStatement不要逃避这个字符串,因为它已经被转义了。谁真正知道JDBC和数据库引擎之间的对话在桌面下发生了什么:也许它根本就没有真正逃脱它,而是将它与查询分开传递。我想在setString上可能有一个额外的参数,说“这个字符串是预转义的”,但这会增加复杂性和潜在的错误,但收益很少。

答案 2 :(得分:3)

请勿使用org.apache.commons.lang.StringEscapeUtils.escapeSql(yourUnscapedSQL);

它不会转义像\

这样的字符

答案 3 :(得分:1)

您可以使用Apache commons中的StringEscapeUtils

org.apache.commons.lang.StringEscapeUtils.escapeSql(yourUnscapedSQL);