使用StringBuffer构建更高效的SQL插入

时间:2016-07-26 20:46:40

标签: java sql

我正在开发一个项目,我创建了一个方法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将数据存储到数据库中。

2 个答案:

答案 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。只是想强调使用字符串缓冲区的优势。