データベースに頻繁にアクセスするポートレットを開発しています。ユーザー入力に対する反応としてフィルタリングの可能性を提供する方法でクエリを指定する必要があります。フィルタリングに使用されるパラメーターは現在 2 つですが、この数は将来的に増える可能性があります。
現時点では、私の構築はすべての入力に対して非常にうまく機能しますが、準備されたステートメントを使用せず、クエリを手動で構築するだけなので、正しい/効果的な方法でそれを行っているとは思いません。
これは私のコードの例です(serviceFilterはarrayListで、typeFlagはStringです)
private String prepareQuery() {
String query = "SELECT * from messages ";
// check filters
if (!typeFlag.equals("ALL")) {
if (typeFlag.equals("XML")) {
query += "WHERE type='" + TYPE_XML + "'";
} else {
query += "WHERE type='" + TYPE_JAVA + "'";
}
}
// lets see if user specifies some service filtering
if (serviceFilter.size() > 0) {
if (!typeFlag.equals("ALL")) {
query += " AND (";
} else {
query += " WHERE (";
}
for (int i = 0; i < serviceFilter.size(); i++) {
if (i>0) {
query += " OR ";
}
String service = serviceFilter.get(i);
System.out.println("Filter: " + service);
query += "sender='" + service + "' OR receiver='" + service + "'";
}
query += ")";
}
query += " ORDER BY id DESC LIMIT " + String.valueOf(limit);
System.out.println(query);
return query;
}
最初の問題は、SQL インジェクションを防ぐ方法がないことです (すべての入力がチェックボックスとスクロールバーから来ているため、ユーザーは実際には何も入力しないため、それほど大きな問題にはなりません)。私のarrayListの人口は非常に長く、クエリごとに変化する可能性があるため、ここで準備済みステートメントを使用する方法がわかりません。
この事実により、クエリ自体が非常に長くなる可能性があります。以下は、引数が 2 つだけのクエリの例です (20 項目の場合を想像してください)。
SELECT * from messages WHERE (sender='GreenServiceESB#GreenListener' OR receiver='GreenServiceESB#GreenListener' OR sender='queue/DeadMessageQueue' OR receiver='queue/DeadMessageQueue') ORDER BY id DESC LIMIT 50
基本的に、私の質問は次のとおりです。これはクエリを作成する効果的な方法ですか (おそらくそうではありません)。どのようなアプローチをお勧めしますか?
PS:何らかの形で重要な場合は、JDBCを使用してdbに接続し、クエリを実行しています...
ヒントをありがとう!