2012-01-10 9 views
0

私は問題があります - 私は自分のSQLクエリを動的に作成し、ユーザーの入力オプションに基づいています。したがって、ユーザーは5つのパラメータを持っています(実際にはそれ以上です)。そして、彼はそれらのいくつか(必要な場合はすべて)を使用するか、またはnoneを選択してクエリの値を指定することができます。そこで、パラメータが選択されているかどうか、値が提供されているかどうかを調べることで、クエリ文字列(WHERE条件の基本)を構築します。しかし今、 'のような特殊文字の問題があります。 replaceAll( "'"、 "\\")を使用しようとする可能性がありますが、これはかなり鈍いですし、preparedStatement.setString()がよりうまく動作することがわかります。しかし、私にとっては、パラメータが提供されているかどうか、また前のパラメータが(もし?の毒を指定してそれを正しいパラメータに接続するために)指定されていれば、再度チェックする必要があります。これは多くの組み合わせを引き起こし、エレガントに見えません。preparedStatem.setString()から文字列を取得できますか?

私の質問は - どういうわけか、preparedStatement.setString()が生成する文字列を受け取ることができますか?または、同じ仕事をし、私に文字列を与えて、手動でクエリに入れることができる同様の関数があります。

イントロが長すぎるかもしれませんが、誰かがより良いアイデアを持っている可能性があります。なぜ私はそれが必要なのか説明したいと思いました。

+1

私は非常にあなたの質問を理解していないが、あなたは絶対に100%のsetStringを使用する必要があります()を自分で行うよりもむしろ。 –

+0

コードの関連部分を含めてください。 –

+0

提供されているパラメータに応じて、 '?'文字を含むクエリ文字列を作成する必要があると思います。クエリ文字列を取得したら、パラメータをもう一度繰り返して、 'setString()'を呼び出します。それがトリックですか? –

答えて

0

あなたができることは、パラメータが指定されているかどうかに基づいて、パラメータ化されていない基本的なSQLクエリを作成し、そのパラメータを満たすためにprepared statementを使用することです。

それはこのような何か(ラフスケッチ)になります:それは唯一のハード初めてです

Map<String, Object> parameterValues = /*from user*/; 
List<String> parameterNames = Arrays.asList("field1", "field2", "field3"); 
List<Object> valueList = new ArrayList<Object>(); 

StringBuilder statementBuilder = new StringBuilder("select * from table where "); 
for (String parameterName : parameterNames) { 
    if (parameterValues.containsKey(parameterName)) { 
     statementBuilder.append(parameterName + " = ? AND"); 
     valueList.add(parameterValues.get(parameterName)); 
    } 
} 

PreparedStatement st = conn.prepareStatement(statementBuilder.toString(), 
         valueList); 
//set each parameter here. 

を。それを一般的にすることができます。それはおそらくあなたのためにこれをすべて抽象化するクエリービルダーがいると言いました。私はQueryDSLを使用していますが、純粋なJDBCのバインディングではなく、JPAやJDOなどのバインディングを持っていません。

+0

マーク - はい私は非常に似てsthをやっています。問題は後でパラメータを設定することです。これが私の質問でした。パラメータには番号が付けられているため、前のパラメータが設定されているかどうかを確認する必要があります。したがって、パラメータBの場合は、パラメータAが設定されているかどうかを確認し、setString(2、parB)を使用し、setString(1、parB)を使用しない場合は使用する必要があります。パラメータCの場合は、AとBをチェックする必要があります。これは1,2、または3の場所にある可能性があるためです。これは難しい部分です。だから、私はsetStringのような値を準備するためにいくつかの関数を使って手動でそれらを置くのです。 –

+0

@ srd.pl:リストのポイントはあなたがそれをする必要がないということでした。単純なforループを実行してインデックスをインクリメントすることができます。 * value *が指定されている場合にのみ値をputするので、リスト内の要素の位置はprepared statementの位置になります。 –

+1

@ mark-peters Querydsl DOESは、Querydsl SQLモジュールでJDBC用のバインディングを持っています。 –