2017-12-14 6 views
0

無限のコードなしでこれを達成するには良い設計パターンは何ですか?JavaでPreparedStatementを構築し、変数を使用してデータベースにデータを挿入する列の数

ユーザが1 ... 100列、1度に23回、別の挿入物に32、別の挿入物に99フィールドを入力するシナリオを考えてみると、毎回異なるフィールドになる可能性があります。

JavaでのPreparedStatementが正しい setIntを確保するために、どのように多くの ?年代 INSERTクエリの値の部分に置くために、最初に入力するためにどのような column namesデータベースのフィールド名のデータ型を知る必要があり

setStringなどです入力されました。

約10列未満の場合、次のロジックを使用してこの問題を回避することができます。

1)variableEnteredForFieldNameがNULLでない場合は、文字列ビルダータイプの設定の形式でクエリの関連部分に追加します。

fieldName_1 

? 

2)は、すべての入力されたフィールド名

3のために同じことを行います)自然field names?

4の両方に存在することになる最終末尾,を取り除く)を作成しますPreparedStatement

5)同じ入力パラメータを再度実行してvariableEnteredForFieldNameがnullでない場合はnullでないことを確認し、既知のデータに基づいてsetIntまたはsetStringを実行しますデータベースに必要な型を指定し、?sの正しいインデックス番号に設定します。

クエリビルダーロジックとクエリフィラーロジックが、パート1とパート2の正しい順序で名前と値を持つ限り、すべて正常に動作します。ただし、PreparedStatementを作成するときに使用するSQLを生成するロジックと、PreparedStatementを満たすロジックを関連付けるコード全体を複製することを意味します。

これは少数の入力パラメータに対しては管理可能ですが、すぐに入力パラメータの数が増えれば管理できなくなります。

同じロジックを達成するためのより良いデザインパターンはありますか?

以下のコードは、上記のすべての概要です。

String fieldName1 = request.getParameter("fieldName1"); 
    String fieldName2 = request.getParameter("fieldName2"); 

    //Build Query 
    String fieldNames = ""; 
    String fieldQuestionMarks = ""; 

    if (fieldName1 != null) { 
     fieldNames = fieldNames + " FIELD_NAME_1 ,"; 
     fieldQuestionMarks = fieldQuestionMarks + " ? ,"; 
    } 

    if (fieldName2 != null) { 
     fieldNames = fieldNames + " FIELD_NAME_2 ,"; 
     fieldQuestionMarks = fieldQuestionMarks + " ? ,"; 
    } 

//Trim the trailing , 
    fieldNames = fieldNames.substring(1, fieldNames.length() - 1); 
    fieldQuestionMarks = fieldQuestionMarks.substring(1, fieldQuestionMarks.length() - 1); 


    try { 
     String completeCreateQuery = "INSERT INTO TABLE_NAME (" + fieldNames + ") VALUES (" + fieldQuestionMarks + ");"; 
     Connection con = DriverManager.getConnection(connectionURL, user, password); 
     PreparedStatement preparedStatement = con.prepareStatement(completeCreateQuery); 

     int parameterIndex = 1; 

     //Fill Query 
     if (fieldName1 != null) { 
      preparedStatement.setString(parameterIndex, fieldName1); 
      parameterIndex++; 
     } 

     if (fieldName2 != null) { 
      preparedStatement.setInt(parameterIndex, Integer.parseInt(fieldName2)); 
      parameterIndex++; 
     } 
    } 

ご覧のとおり、これは可能です。しかし、わずか2フィールドのオプションフィールドでも、このコードは膨大です。

+0

すべてのフィールドをハードコードする代わりにループを使用しない限り、「巨大」です。これは、フィールド名と値を 'Map'データ構造に入れることを含むかもしれません。 –

+0

正しい。しかし、キー/値ストアであるMapでは、フィールドのデータ型は考慮されません。 –

答えて

0

ユーザーがリストから列のいずれかを省略できる場合、すべての列はオプションであり、挿入時にNULLに設定することができます。したがって、必要なのは、すべての列がリストされた、 "モンスター" INSERTを持つ1つの準備済みステートメントです。実際の挿入操作では、ユーザー提供のデータをループし、指定された列の値を設定し、省略された列に対してはsetNull()を呼び出します。あなたはどこかで(あなたのDAOクラスの可能性が高い)構造体をSQL文の中でその順序にマッピングする必要があります。

+0

@ジムギャリソン:downvoteをしてください。私が見たように、リンクされた質問はどちらも実用的な解決法を提案していませんでした(実際にINSERTリストを動的に作成しましたか?)、また私の提案は実際にそこに提案されていません –

+0

私はこの答えがなぜすばやく投票されたのか疑問に思いました。私にとってこれはあなたがアレックスに提供した完璧な解決策です。これは私が単に上記のモンスターINSERTステートメントを作成することができ、ユーザーがこのパラメーターのデータを入力していない場合は、単にあなたが言及しているsetNull()オプションを使用することができます。私はその機能を知らなかった。ありがとう。 –

関連する問題