2016-07-26 8 views
0

私はプロジェクトに取り組んでおり、私はSQL挿入ステートメントを構成する文字列バッファを作成するinsertStatement()メソッドを作成しました。ここでは、次のとおりです。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として返します。この文字列は、ItemWriterに渡される配列リストに移入され、データベースにデータが格納されます。

+5

はい、['PreparedStatement'](https://docs.oracle.com/javase/7/docs/api/java/sql/PreparedStatement.html)を使用し、自分自身をSQLインジェクションに開放しないでください。 – khelwood

+1

'PreparedStatement'のようなものを使用できない理由はありますか?次に、PreparedStatement pstmt = databaseConnection.prepareStatement( "Customer、name、city、state)の値(?、?、?、?)")に挿入し、その後にpstmt.setString( 1、this.custName); – 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

あなたのコードは、メモリ内の文字列インスタンス(**を使用して)強調表示:

あなたは+ 4 "'" 合計(4つの文字列変数に持つ変数this.custName、this.custNumなどを数える
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(); 
} 

この関数が呼び出されたときにメモリ内に17個の文字列オブジェクトインスタンスが連結されたときに+ 4 "'、" +4文字列インスタンスが作成されます。

 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列バッファインスタンス

なぜ作るのだろうか? 文字列は不変であるため、作成した文字列を変更または変更することはできません。

ここで重要ですか?ループ内で何百万回も呼び出さない限り、おそらくそれは約17万回になるでしょう。インスタンスがメモリ文字列オブジェクトに含まれていて、メモリが不足する可能性があります。

また、このコメントは非常に有効で、この場合はPrepared Statementを使用する必要があります。文字列バッファを使用する利点を強調したかっただけです。

関連する問題