2

データベースシステムを構築する目的で、私は単純なビルダーを使用して、ユーザーの選択に基づいて選択クエリを生成しています。ブール値がいくつかあり、次のように進行します

    StringBuilder builder = new StringBuilder();
    builder.append("SELECT ");
    if(addOpen)
        builder.append("Open ");
    if(addHigh)
        builder.append("High ");
    if(addLow)
        builder.append("Low ");
    if(addSettle)
        builder.append("Settle ");
    builder.append("FROM " + tableName);

さて、私の問題は些細なことです-カンマを含める必要がありますが、カンマを含める場合は、その後に値が続く必要があるため、Open、Open、Closeなどを実行できません。この些細な問題に対する適切な解決策はありますか?私にとって驚くほど難しい問題ですか?

4

6 に答える 6

4

Apache CommonsのStringUtils.join()メソッドのようなものをお探しですか?すなわち:

Collection<String> selections = Arrays.asList("Open", "Low");
String clause = StringUtils.join(selections, ',');

それならただ

String sql = "SELECT " + clause + " FROM " + TableName;
于 2012-05-22T23:19:19.847 に答える
3

1)典型的なケースは、あなたが持っているアイテムの数をアプリオリに知っていることです。したがって、「n-1」をループするだけで、最後の項目にコンマを追加しないでください。

2)1つの可能な解決策:

  ArrayList<string> items = new ArrayList<String>();
  if(addOpen);
    items.add("Open ");
  if(addHigh)
    items.add("High ");
  if(addLow)
    items.add("Low ");
  if(addSettle)
    items.add("Settle ");

  StringBuilder builder = new StringBuilder();
  int i=0;
  for (i=0; i < items.size() - 1; i++) {
    builder.append(items[i] + ",");
  }
  builder.append(items[i] + "FROM " + tableName);
  ...
于 2012-05-22T23:23:10.877 に答える
1

一般的なトリックがあります:あなたが興味を持っていない定数を常に選択してください:

builder.append ("SELECT 1 ");
if (addOpen)
    builder.append (", Open ");
if addHigh)
    builder.append (", High ");
if (addLow)
    builder.append (", Low ");
if (addSettle)
    builder.append (", Settle ");
builder.append ("FROM " + tableName);

別のアプローチは、末尾にコンマを使用して、反対方向に機能します。

builder.append ("SELECT ");
if (addOpen)
    builder.append ("Open, ");
if (addHigh)
    builder.append ("High, ");
if (addLow)
    builder.append ("Low, ");
if (addSettle)
    builder.append ("Settle, ");
builder.append ("1 FROM " + tableName);
于 2012-05-22T23:19:19.050 に答える
1

いくつかの方法があります。最初の選択肢は、SQLステートメントをまったく作成せず、フィールドを表示しないことです。

2つ目は、文字列を作成し、最後のカンマを削除することです。

3つ目は、各フィールド名を配列に入れ、最後の要素に末尾のコンマを付けずに、配列をループすることです。

于 2012-05-22T23:20:59.900 に答える
0

私が使用するトリック(一般的な半型なしの擬似コード)は次のとおりです。

 pad = ""    # Empty string

 builder = "SELECT ";
 if (addOpen)
     builder += pad + "Open";   pad = ", ";
 if (addHigh)
     builder += pad + "High";   pad = ", ";
 if (addLow)
     builder += pad + "Low";    pad = ", ";
 if (addSettle)
     builder += pad + "Settle"; pad = ", ";
 builder += "FROM " + TableName;

私が見た別の方法は、用語の後に常にコンマ(またはコンマスペース)を含めることですが、FROM句を追加する前に最後の2文字を値から削除します。あなたの選択...「パッド」テクニックは、出力を行っていて、追加を元に戻すことができない場合でも機能します。

于 2012-05-22T23:20:11.360 に答える
0

あなたの状況では、Ryan Stewartが提案したものと同様のソリューションを使用しますが、ApacheCommonsではなくGoogleGuavaを使用します。私はこのライブラリを好みます。なぜなら、Apacheライブラリは巨大で相互に関連していると感じているからです。以下は、SQL文字列を作成する方法です。

import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import java.util.List;

public class SqlJoiner {
    public String buildSql(
            boolean addOpen,
            boolean addHigh,
            boolean addLow,
            boolean addSettle,
            String tableName
    ) {
        Preconditions.checkArgument(!Strings.isNullOrEmpty(tableName));
        Preconditions.checkArgument(addOpen | addHigh | addLow | addSettle );

        final List<String> clauses = Lists.newArrayList();

        if (addOpen) clauses.add("Open");
        if (addHigh) clauses.add("High");
        if (addLow) clauses.add("Low");
        if (addSettle) clauses.add("Settle");

        StringBuilder builder = new StringBuilder();
        builder.append("SELECT ");
        builder.append(Joiner.on(',').join(clauses));
        builder.append(" FROM " + tableName);
        return builder.toString();
    }

}

メソッド本体の先頭の前提条件は、ブールオプションの少なくとも1つが常にtrueであり、tableNameがnullまたは空でないことを確認することを目的としています。コードの前提条件を常に確認してください。将来、コードの使用を間違えた場合に多くの問題を回避できます。

于 2012-05-23T06:32:54.860 に答える