高效地进行Java字符串替换

高效地进行Java字符串替换,java,string,performance,replace,Java,String,Performance,Replace,我们有以下代码: String templateQuery = "select * from my_table where col1=$1 or col2 like '%$2.$1'"; String tmp = templateQuery; for(int i=1;i<=maxCols;i++) { tmp = tmp.replaceAll("\\$"+i, data[i-1]); } String templateQuery=“从my_表中选择*,其中col1=$1或类似于

我们有以下代码:

String templateQuery = "select * from my_table where col1=$1 or col2 like '%$2.$1'";
String tmp = templateQuery;

for(int i=1;i<=maxCols;i++) {
    tmp = tmp.replaceAll("\\$"+i, data[i-1]);
}
String templateQuery=“从my_表中选择*,其中col1=$1或类似于“%$2.$1”的col2;
字符串tmp=templateQuery;

对于(int i=1;i他是正确的,因为您创建了maxCols tmp字符串。 我意识到它是用于Sql命令的,如果是,为什么不使用PreparedStatement(http://download.oracle.com/javase/1.4.2/docs/api/java/sql/PreparedStatement.html)为了这个任务


另外,对于格式化字符串,使用Formatter比使用substitute要优雅得多:

他是正确的,因为您创建了maxCols tmp字符串。 我意识到它是用于Sql命令的,如果是,为什么不使用PreparedStatement(http://download.oracle.com/javase/1.4.2/docs/api/java/sql/PreparedStatement.html)为了这个任务


另外,对于格式化字符串,与其使用替换,不如使用Formatter,它要优雅得多:

为什么不使用带替换参数的

String templateQuery = "SELECT * FROM my_table WHERE col1 = ?";
PreparedStatement ps = con.prepareStatement(templateQuery);
for (int i = 0; i < data.length; i++) {
    ps.setString(i + 1, data[i]);
}
ResultSet rs = ps.executeQuery();
String templateQuery=“从我的表格中选择*,其中col1=?”;
PreparedStatement ps=con.prepareStatement(templateQuery);
对于(int i=0;i

如果您像以前一样使用字符串替换,则很容易受到攻击。

为什么不使用带替换参数的字符串替换

String templateQuery = "SELECT * FROM my_table WHERE col1 = ?";
PreparedStatement ps = con.prepareStatement(templateQuery);
for (int i = 0; i < data.length; i++) {
    ps.setString(i + 1, data[i]);
}
ResultSet rs = ps.executeQuery();
String templateQuery=“从我的表格中选择*,其中col1=?”;
PreparedStatement ps=con.prepareStatement(templateQuery);
对于(int i=0;i

如果您像以前一样使用字符串替换,则很容易受到攻击。

不要这样做。

不是出于性能原因(与数据库查询的成本相比微不足道),而是为了避免SQL注入攻击。如果
data[0]
实际上是字符串,会发生什么

' OR 'x' = 'x
?

然后,您将得到以下SQL语句:

SELECT * FROM my_table WHERE col1='' OR 'x' = 'x'
我想我们可以同意这不是你想要的

改为使用参数化SQL语句()并让数据库驱动程序单独发送参数值


编辑:在其他评论中,OP规定模板字符串可能相当长,一些参数实际上可能涉及多个初始值组合在一起。我仍然认为,在总体方案中,替换成本可能微不足道,我仍然认为
PreparedStatement
是一条可行之路。在将输入设置为
PreparedStatement
的值之前,应该对输入执行任何需要的组合操作,因此模板可能需要SQL和SQL占位符,然后是“子模板”要了解如何从您的输入获取
PreparedStatement
的参数,无论您做什么,将值直接放入SQL都是错误的方法。

不要这样做。

不是出于性能原因(与数据库查询的成本相比微不足道),而是为了避免SQL注入攻击。如果
data[0]
实际上是字符串,会发生什么

' OR 'x' = 'x
?

然后,您将得到以下SQL语句:

SELECT * FROM my_table WHERE col1='' OR 'x' = 'x'
我想我们可以同意这不是你想要的

改为使用参数化SQL语句()并让数据库驱动程序单独发送参数值


编辑:在其他评论中,OP规定模板字符串可能相当长,一些参数实际上可能涉及多个初始值组合在一起。我仍然认为,在总体方案中,替换成本可能微不足道,我仍然认为
PreparedStatement
是一条可行之路。在将输入设置为
PreparedStatement
的值之前,应该对输入执行任何需要的组合操作,因此模板可能需要SQL和SQL占位符,然后是“子模板”要解决如何从您的输入获取
PreparedStatement
的参数,无论您做什么,将值直接放入SQL都是错误的方法。

您的同事是对的,每次字符串替换都会创建一个新的字符串副本。(但是,如果参数少于10个,那么这些查询的成本可能可以忽略不计。)此外,对于每次执行此查询,SQL引擎都需要重新解析它,这每次都会消耗更多的额外资源

然而,潜在的更大问题是,代码支持SQL注入。如果输入数据来自外部源,黑客可以传入参数,如
“col1;drop table my_table;”
,从而有效地删除整个表


所有这些问题都可以通过使用替换来解决。

您的同事是对的,每次字符串替换都会创建一个新的字符串副本。(但是,如果参数不到10个,这些操作的成本可能可以忽略不计。)此外,对于此查询的每次执行,SQL引擎都需要重新解析它,这每次都会消耗更多的额外资源

然而,潜在的更大问题是,代码支持SQL注入。如果输入数据来自外部源,黑客可以传入参数,如
“col1;drop table my_table;”
,从而有效地删除整个表


所有这些问题都可以通过使用解决。

这是否会消耗太多内存还有待讨论(什么是“太多”?)


尽管如此,对于这种类型的东西,你还是应该使用它。它可以让你以一种更干净的方式完成你想要完成的事情。

这是否会消耗太多内存还有待讨论(什么是“太多”?)

尽管如此,对于这类东西,你还是应该使用它。它可以让你以一种更干净的方式完成你想要完成的事情。

Define“work”