PHP的Java等价物';s mysql\u real\u escape\u string()
是否有与PHP的mysql_real_escape_string()等价的Java 这是为了在将SQL注入尝试传递给Statement.execute()之前对其进行转义 我知道我可以用PreparedStatement来代替,但是让我们假设这些是一次性语句,所以准备它们会导致错误。我已经将代码更改为使用PreparedStatement,但是考虑到现有代码的结构,使用escape()函数将使代码更改更易于查看和维护;我更喜欢易于维护的代码,除非对于额外的复杂性有令人信服的理由。此外,数据库对PreparedStatements的处理方式也不同,因此这可能会使我们暴露在数据库中以前从未遇到过的错误中,需要在发布到生产环境之前进行更多测试 仅转义单引号 附言: 在我继承的环境中有很多微妙之处,我在问题中故意回避 有两点需要考虑: 1) 准备好的语句不是万能的,也不能提供100%的SQL注入保护。某些数据库驱动程序使用不安全的字符串连接实例化参数化查询,而不是将查询预编译为二进制形式。此外,如果SQL依赖于存储过程,则需要确保存储过程本身不会以不安全的方式生成查询 2) 大多数准备好的语句实现都会将该语句绑定到实例化该语句的数据库连接。如果您使用的是数据库连接池,则需要小心PHP的Java等价物';s mysql\u real\u escape\u string(),java,sql,mysql,security,jdbc,Java,Sql,Mysql,Security,Jdbc,是否有与PHP的mysql_real_escape_string()等价的Java 这是为了在将SQL注入尝试传递给Statement.execute()之前对其进行转义 我知道我可以用PreparedStatement来代替,但是让我们假设这些是一次性语句,所以准备它们会导致错误。我已经将代码更改为使用PreparedStatement,但是考虑到现有代码的结构,使用escape()函数将使代码更改更易于查看和维护;我更喜欢易于维护的代码,除非对于额外的复杂性有令人信服的理由。此外,数据库对P
仅对准备好的语句引用的连接使用该语句引用。一些池机制确实透明地实现了这一点。否则,您也可以将准备好的语句合并在一起,或者(最简单但开销更大)为每个查询创建一个新的准备好的语句。不要假设准备好的语句速度较慢。试一下,量一下,然后判断
PreparedStatements应该总是优先于Statement使用,几乎没有例外,尤其是当您试图避免SQL注入攻击时。避免SQL注入的唯一合理方法是使用prepared/参数化语句
例如,由于某种原因,您试图避免的错误。如果你只做一次陈述,准备它们的时间应该可以忽略不计(“一次”和“关键绩效”是矛盾的,IMHO)。如果在循环中进行操作,准备好的语句甚至会导致性能提高。据我所知,没有“标准”的方法可以做到这一点 我强烈建议使用事先准备好的声明,尽管您目前对此表示担忧。对性能的影响可以忽略不计——我们有一个类似的情况,每秒有几千条语句——大多数也是一次 您获得的安全性应该比您尚未看到的性能问题更重要。在我看来,这是一个“不要过早优化”的明显情况 在任何情况下,如果您以后真的发现您遇到了性能问题,请通过仔细分析确保准备好的语句是真正的原因,然后寻找替代方案。在那之前,你应该省去试图正确逃跑的麻烦
这一点更为重要,因为我推断您正在开发某种面向公众的网站——内部应用程序很少获得足够的流量来关注性能 下面是一些代码,它实现了您想要的功能。最初在Vnet发布wiki上
/**
*Mysql实用程序
*
*@作者拉尔夫·里托赫
*@版权所有Ralph Ritoch 2011版权所有
*@linkhttp://www.vnetpublishing.com
*
*/
包vnet.java.util;
公共类MySQLUtils{
/**
*要防止SQL注入的转义字符串
*
*您必须在此函数的结果周围为数据添加一个单引号,
*或者在表和行标识符周围打勾。
*如果此函数返回null,则应更改结果
*设置为“NULL”,不带任何引号或反勾号。
*
*@param-link
*@param str
*@返回
*@抛出异常
*/
公共静态字符串mysql\u real\u escape\u String(java.sql.Connection link,String str)
抛出异常
{
如果(str==null){
返回null;
}
如果(str.replaceAll(“[a-zA-Z0-9#$%^&*()-=+~.;:,\\Q[\\E\\Q]\\E{}\\/?]”,则“).length()<1){
返回str;
}
String clean_String=str;
clean\u string=clean\u string.replaceAll(“\\\\”,“\\\”);
clean\u string=clean\u string.replaceAll(“\\n”,“\\\\n”);
clean\u string=clean\u string.replaceAll(“\\r”,“\\\\r”);
clean\u string=clean\u string.replaceAll(“\\t”,“\\\\t”);
clean\u string=clean\u string.replaceAll(“\\00”,“\\\\0”);
clean\u string=clean\u string.replaceAll(“'”,“\\\\”);
clean\u string=clean\u string.replaceAll(“\\\”,“\\”);
if(clean\u string.replaceAll(“[a-zA-Z0-9\@$%^&*()-=+~.:,\\Q[\\E\\Q]\\E{}\\/?”
,“”)。长度()
{
返回干净的字符串;
}
java.sql.Statement stmt=link.createStatement();
String qry=“选择引号(“+clean_String+”)”;
标准执行机构(qry);
java.sql.ResultSet ResultSet=stmt.getResultSet();
resultSet.first();
字符串r=resultSet.getString(1);
返回r.substring(1,r.length()-1);
}
/**
*转义数据以防止SQL注入
*
*@param-link
*@param str
*@返回
*@抛出异常
*/
公共静态字符串引号(java.sql.Connection链接,字符串str)
抛出异常
{
如果(str==null){
返回“NULL”;
}
返回“'”
/**
* Mysql Utilities
*
* @author Ralph Ritoch <rritoch@gmail.com>
* @copyright Ralph Ritoch 2011 ALL RIGHTS RESERVED
* @link http://www.vnetpublishing.com
*
*/
package vnet.java.util;
public class MySQLUtils {
/**
* Escape string to protected against SQL Injection
*
* You must add a single quote ' around the result of this function for data,
* or a backtick ` around table and row identifiers.
* If this function returns null than the result should be changed
* to "NULL" without any quote or backtick.
*
* @param link
* @param str
* @return
* @throws Exception
*/
public static String mysql_real_escape_string(java.sql.Connection link, String str)
throws Exception
{
if (str == null) {
return null;
}
if (str.replaceAll("[a-zA-Z0-9_!@#$%^&*()-=+~.;:,\\Q[\\E\\Q]\\E<>{}\\/? ]","").length() < 1) {
return str;
}
String clean_string = str;
clean_string = clean_string.replaceAll("\\\\", "\\\\\\\\");
clean_string = clean_string.replaceAll("\\n","\\\\n");
clean_string = clean_string.replaceAll("\\r", "\\\\r");
clean_string = clean_string.replaceAll("\\t", "\\\\t");
clean_string = clean_string.replaceAll("\\00", "\\\\0");
clean_string = clean_string.replaceAll("'", "\\\\'");
clean_string = clean_string.replaceAll("\\\"", "\\\\\"");
if (clean_string.replaceAll("[a-zA-Z0-9_!@#$%^&*()-=+~.;:,\\Q[\\E\\Q]\\E<>{}\\/?\\\\\"' ]"
,"").length() < 1)
{
return clean_string;
}
java.sql.Statement stmt = link.createStatement();
String qry = "SELECT QUOTE('"+clean_string+"')";
stmt.executeQuery(qry);
java.sql.ResultSet resultSet = stmt.getResultSet();
resultSet.first();
String r = resultSet.getString(1);
return r.substring(1,r.length() - 1);
}
/**
* Escape data to protected against SQL Injection
*
* @param link
* @param str
* @return
* @throws Exception
*/
public static String quote(java.sql.Connection link, String str)
throws Exception
{
if (str == null) {
return "NULL";
}
return "'"+mysql_real_escape_string(link,str)+"'";
}
/**
* Escape identifier to protected against SQL Injection
*
* @param link
* @param str
* @return
* @throws Exception
*/
public static String nameQuote(java.sql.Connection link, String str)
throws Exception
{
if (str == null) {
return "NULL";
}
return "`"+mysql_real_escape_string(link,str)+"`";
}
}
state.execute("insert into extractiontext(extractedtext,extractedgroup) values('"+content+"','"+group+"')");
} catch (Exception e) {
e.printStackTrace();
}
SQLBuilder sqlBuilder = new SQLBuilder("update ").append(dbName).append(".COFFEES ");
sqlBuilder.append("set SALES = ").escapeString(sales);
sqlBuilder.append(", TOTAL = ").escapeInt(total);
sqlBuilder.append("where COF_NAME = ").escapeString(coffeeName);
sqlBuilder.prepareStatement(connection).executeUpdate();
class SQLBuilder implements Appendable {
private StringBuilder sqlBuilder;
private List<Object> values = new ArrayList<>();
public SQLBuilder() {
sqlBuilder = new StringBuilder();
}
public SQLBuilder(String str)
{
sqlBuilder = new StringBuilder(str);
}
@Override
public SQLBuilder append(CharSequence csq)
{
sqlBuilder.append(csq);
return this;
}
@Override
public SQLBuilder append(CharSequence csq, int start, int end)
{
sqlBuilder.append(csq, start, end);
return this;
}
@Override
public SQLBuilder append(char c)
{
sqlBuilder.append(c);
return this;
}
// you can add other supported parameter types here...
public SQLBuilder escapeString(String x)
{
protect(x);
return this;
}
public SQLBuilder escapeInt(int x)
{
protect(x);
return this;
}
private void escape(Object o)
{
sqlBuilder.append('?');
values.add(o);
}
public PreparedStatement prepareStatement(Connection connection)
throws SQLException
{
PreparedStatement preparedStatement =
connection.prepareStatement(sqlBuilder.toString());
for (int i = 0; i < values.size(); i++)
{
Object value = values.get(i);
// you can add other supported parameter types here...
if (value instanceof String)
preparedStatement.setString(i + 1, (String) value);
else if (value instanceof Integer)
preparedStatement.setInt(i + 1, (Integer) value);
}
return preparedStatement;
}
@Override
public String toString()
{
return "SQLBuilder: " + sqlBuilder.toString();
}
}