使用逗号分隔值构建字符串

时间:2012-05-22 23:10:35

标签: java sql string stringbuilder

为了构建数据库系统,我使用一个简单的构建器来根据用户选择生成选择查询。它有几个布尔值然后它进展如下

    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);

现在,我的问题很简单 - 我需要包含逗号,但是如果我包含一个逗号,那么必须有一个值,所以我不能打开,打开,关闭等等。这是否有一个简洁的解决方案琐碎的,但令我难以置信的问题?

6 个答案:

答案 0 :(得分:4)

您是否正在寻找类似Apache Commons' StringUtils.join()方法的内容?即:

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

然后只是

String sql = "SELECT " + clause + " FROM " + TableName;

答案 1 :(得分:3)

1)典型的情况是你先前知道你有多少物品。所以你只需循环“n-1”,然后不要在最后一项附加逗号。

2)一种可能的解决方案:

  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);
  ...

答案 2 :(得分: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);

答案 3 :(得分:1)

有两种方法。第一个,这是我的第一选择,是根本不构建你的SQL语句,只是不显示字段。

第二个是,构建字符串,然后删除最后一个逗号。

第三个是将每个字段名称放入一个数组中,并循环遍历数组,而不是在最后一个元素上放置尾随逗号。

答案 4 :(得分: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子句之前修剪掉该值的最后两个字符。你的选择......'pad'技术即使你正在输出也无法撤消追加。

答案 5 :(得分:0)

在你的情况下,我使用Ryan Stewart建议的类似解决方案,但我更喜欢Google Guava而不是Apache Commons。我更喜欢这个库,因为我觉得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();
    }

}

方法体开头的前提条件是确保至少有一个布尔选项始终为true,并且tableName不为null或为空。始终检查代码的前提条件,将来如果您在使用代码时出错将会省去很多麻烦!