2012-04-24 9 views
2

私のJavaプロジェクトに問題があります。機能次StringBuilder.append(String str)で何か狂ったことが起こりました。

は、SQL文の文字列を提供する必要があります。

private static String createInsertString(Pat p) 
{ 
    StringBuilder x = new StringBuilder(); 


    x.append("" + p.getPatnr() +","+ p.getSvnr()); 

    java.sql.Date andat = null,gebdat; 

    if(p.getAndat()==null) 
     andat=null; 
    else 
     andat=new java.sql.Date(p.getAndat().getTimeInMillis()); 

    if(p.getGebdat()==null) 
     gebdat=null; 
    else 
     gebdat=new java.sql.Date(p.getGebdat().getTimeInMillis()); 

    x.append("," + andat==null?"null":andat); 
    x.append("," + p.getTele()==null?"null":p.getTele()); 
    x.append("," + p.getVName() +","+ p.getNname()); 
    x.append("," + p.getKk()==null?"null":p.getKk()); 
    x.append("," + gebdat==null?"null":gebdat); 
    x.append("," + p.getAdrplzort()==null?"null":6); 
    x.append("," + p.getAdrstr()==null?"null":p.getAdrstr()); 
    x.append("," + p.getAdrhnr()==null?"null":p.getAdrhnr()); 
    s.append("," + p.getReplzort()==null?"null":p.getReplzort().getPlzortnr()); 
    x.append("," + p.getRestr()==null?"null":p.getRestr()); 
    x.append("," + p.getRehnr()==null?"null":p.getRehnr()); 
    x.append("," + p.getLevel()); 
    x.append("," + p.getCon()==null?"null":p.getCon()); 
    x.append("," + (p.isPa()?"y":"n")+","+ (p.isLonly()?"y":"n") +","+ (p.isGest()?"y":"n")); 
    x.append("," + p.getBem()==null?"null":p.getBem()); 
    x.append("," + (p.isKat1()?'y':'n') +","+ (p.isKat2()?'y':'n') +","+ (p.isKat3()?'y':'n')); 

    System.out.println(x); 

    return x.toString(); 
} 

出力は

6,6465136nullnull,Jürgen,Wieslernullnull6nullnullnullnull,0null,n,n,nnull,n,n,n 

ですが、それはこのようにする必要があります:

6,6465136,null,null,Jürgen,Wiesler,null,null,6,null,null,null,null,0,null,n,n,n,null,n,n,n 

誰でもアイデア? 私はdebian(64ビット)でjdk 1.7を使用しています

+0

カップルの人が既に問題を見つけて、あなたに以下の答えを与えましたが、ランダムな質問があります。 'java.sql.Date andat = null、gebdat;'とは何ですか?それは私がまだ見ていないオブジェクトを初期化するための新しい方法ですか?私は完全に空白であり、私が答えを見ると本当に愚かな気がしますか? – Windle

+1

あなたは "s"に一度追加すると、それはタイプミスですか? –

+1

これを見ると、 'java.sql.PreparedStatement'の使用を検討することができます。動的SQLを使用すると、注入脆弱性が誘発されます。 –

答えて

11

問題はオペレータのバインド方法です。これを見て:LHSはがnullになるだろうことはありませんので、それは常にちょうどandatを追加...とまだ変換します

x.append(("," + andat) == null ? "null" : andat); 

x.append("," + andat==null?"null":andat); 

は今と考えますデフォルトの動作がStringBuilderなので、参照がnullの場合はnullに設定します。

あなたのコードはです。多くの場合、より複雑で非効率的です。

x.append("," + p.getVName() +","+ p.getNname()); 

これらは、2つの異なるゲッターを呼び出すことを意味:私はあなたが元のバグを持っていたと思います

private static String createInsertString(Pat p) 
{ 
    StringBuilder x = new StringBuilder(); 
    java.sql.Date andat = p.andat == null ? null 
     : new java.sql.Date(p.getAndat().getTimeInMillis()); 
    java.sql.Date gebdat = p.getGebdat() == null ? null 
     : new java.sql.Date(p.getGebdat().getTimeInMillis()); 

    x.append(p.getPatnr()).append(",") 
    .append(p.getSvnr()).append(",") 
    .append(andat).append(",") 
    .append(p.getTele()).append(",") 

    // etc 

    return x.toString(); 
} 

注:としてそれを書き換えて考えてみましょうか?

+0

+1:チェックは、 'x.append("、 "+ andat);と同じですが、' x.append( "、" +(andat == null? ' –

+0

これはStringBuilderを必要としません。シンプルな文字列連結もうまく動作します。 – Robin

+0

@Robin:はい、それはすべて1つの式で実行できるのでしょうか?かなり巨大な表現ではありますが、現時点では可能性があります。この方法で余分なロジックを追加する方が簡単です。 –

3

問題は「+」の問題です。

  1. あなたはStringBuilderのを使用する場合は、 '+' を使用しないでください:andatがnullの場合、それは",null"==null?"null":andat
  2. "," + andat==null?"null":andat結果、効率的ではありません。

「+」文字列連結は三項演算子に優先しますが、文字列で「+」を使用する場合

コンパイラが実際のStringBuilder(またはJava5前にStringBuffer)にあることを翻訳

を持っています

String s = new StringBuilder().append(a).append(b).append(c).toString(). 
:だから

String s = a + b + c; 

が実際に翻訳されました

したがって、StringBuilder内で+を使用すると、追加の不要なStringBuilderを作成するため、生産性が低下します。

4

.append()を連結して使用しています。これはStringBuilderが使用されるはずのポイント全体を逃してしまいます。

x.append("," + andat==null?"null":andat); 

は、あなたが意図したとおりに、あなたの三項演算子を動作させるために正しいロジックだろう

x.append(",").append(andat == null ? "null" : andat); 

でなければなりません。

.append()は、への参照を返します。必要に応じて.append()コールをチェーンできるようにします。

.append()の中に文字列連結を入れているときは、メモリ、CPUサイクルを使い果たし、今やガベージコレクションする必要があるため、より多くのリソースを使用するオブジェクトを作成するだけです。

また、StringBuilderの既定のサイズは、無駄な割り当てや不要な作成を避けるためにコンテンツが予想されるサイズよりわずかに大きいものを事前に割り当てる必要があります。

StringBuilder(int)コンストラクタについては、Javadocを参照してください。

関連する問題