我正在开发一个项目,我创建了一个方法insertStatement()
,它创建了一个构造我的SQL insert语句的字符串缓冲区。这是:
private String insertStatement() {
StringBuffer sb = new StringBuffer(
"insert into CUSTOMER (NAME, NUMBER, CITY, STATE) values (");
sb.append("'" + this.custName + "',");
sb.append("'" + this.custNum + "',");
sb.append("'" + this.custCity + "',");
sb.append("'" + this.custState + ")");
return sb.toString();
}
我想知道是否有更有效的方法来构建此语句,而不必在开头添加'
并在结尾添加',
。
问题的更多细节。我正在创建一个批处理作业,并且此方法将语句作为String返回,然后将填充将传递给ItemWriter的Array List,然后ItemWriter将数据存储到数据库中。
答案 0 :(得分:3)
不要使用StringBuffer
。它被StringBuilder
取代。使用PreparedStatement
;它是类型安全的,可以防止SQL注入攻击。
如果您确实使用StringBuilder
来构建字符串,请不要在append
序列中进行内联字符串连接;只需使用append
。
至于预先添加(不是“追加”)引用并附加引号,这是构建不安全SQL字符串的工件,并且在该上下文中是不可避免的。 PreparedStatement
会为您处理。
答案 1 :(得分:1)
您的代码,在内存中突出显示(使用**)字符串实例:
private String insertStatement() {
StringBuffer sb = new StringBuffer(
**"insert into CUSTOMER (NAME, NUMBER, CITY, STATE) values ("**);
sb.append(**"'"** + this.custName + **"',"**);
sb.append(**"'"** + this.custNum + **"',"**);
sb.append(**"'"** + this.custCity + **"',"**);
sb.append(**"'"** + this.custState + **")"**);
return sb.toString();
}
计算你总共拥有的变量this.custName,this.custNum等(4个字符串变量+ 4"'" + 4"',&# 34;在连接内容时创建的+ 4个字符串实例+ 1个字符串构建器实例)=在调用此函数时内存中的17个字符串对象实例。
private String insertStatement() {
StringBuffer sb = new StringBuffer(
"insert into CUSTOMER (NAME, NUMBER, CITY, STATE) values (");
String quote = "'";
String endQuoteComma = "',";
String endingBracket = ")";
sb.append(quote);
sb.append(this.custName);
sb.append(endQuoteComma);
sb.append(quote);
sb.append(this.custNum);
sb.append(endQuoteComma);
sb.append(quote);
sb.append(this.custCity);
sb.append(endQuoteComma);
sb.append(quote);
sb.append(this.custState);
sb.append(endingBracket);
return sb.toString();
}
此版本将在内存中创建8个字符串实例,4个变量+ 3个引号,endquotecomma,endbracket变量+ 1个字符串缓冲区实例
为什么呢? 由于字符串是不可变的,因此在创建字符串后无法更改或修改字符串。
这在这里重要吗?可能不会,除非你在一个循环内调用它一百万次,这将产生约1700万。内存字符串对象中的实例,最终可能会耗尽内存。
我也认为这些评论非常有效,在这种情况下你应该使用Prepared Statement。只是想强调使用字符串缓冲区的优势。