2016-07-26 33 views
0

我正在創建一個項目,並創建了一個方法insertStatement(),它創建了一個構造我的SQL插入語句的字符串緩衝區。那就是:使用StringBuffer構建更高效的SQL插入

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返回,然後將填充一個Array List,該List將傳遞給ItemWriter,然後將該數據存儲到數據庫中。

+5

是的,使用['PreparedStatement'](https://docs.oracle.com/javase/7/docs/api/java/sql/PreparedStatement.html),不要讓自己打開SQL注入。 – khelwood

+1

有沒有理由不能使用諸如'PreparedStatement'之類的東西?然後你可以像'PreparedStatement pstmt = databaseConnection.prepareStatement(「insert into Customer(name,number,city,state)values(?,?,?,?)」);'然後替換爲pstmt.setString( 1,this.custName); etc – Orin

+0

我沒有很多使用數據庫的經驗,所以我不知道'PreparedStatement'是一個選項!我會看一看。 –

回答

3

千萬不要使用StringBuffer。它已被StringBuilder取代。使用PreparedStatement;它的類型安全並防止SQL注入攻擊。

如果你使用StringBuilder構建字符串,便意,不做append序列內聯字符串拼接;只需使用append即可。

關於預先(不附加)引用和附加引號逗號,這是構建不安全的SQL字符串的工件,並且在該上下文中是不可避免的。 PreparedStatement將爲您處理。

+0

這是有道理的,我正在看這個[link](http://www.tutorialspoint.com/javaexamples/jdbc_prepared_statement.htm),我發現他們正在連接到一個數據庫。我只是簡單地構造語句,將其傳遞迴語句的ArrayList,然後將其傳遞給ItemWriter(它將寫入數據庫)。所以我想知道我是否仍然應該遵循這個程序? –

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「',」+連接東西時創建的+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。只是想強調使用字符串緩衝區的優點。