2012-05-22 28 views
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); 

现在,我的问题是微不足道的 - 我需要包括逗号,但如果我有一个逗号必有后它的到来值,所以我不能做打开还是打开,关闭等等。对于这个微不足道的问题,是否有一个简洁的解决方案,但对我来说却难以置信?

回答

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”技术也能正常工作。

+1

破碎。你需要在身体周围的括号。 –

+1

不在我的伪代码中,我没有。 –

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

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

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

然后,只需

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

有几种方法。第一个,这将是我的第一选择,不要根本建立你的SQL语句,而不要显示这些字段。

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

第三种方法是将每个字段名称放入一个数组中,并循环访问该数组,而不是将尾随逗号放在最后一个元素上。

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

在你情我使用性相似,通过赖恩·斯图尔特提出了一个解决方案,但我更喜欢谷歌Guava而不是Apache的百科全书。我更喜欢这个库,因为我觉得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(); 
    } 

} 

在方法体开始时的前提条件是为了确保该布尔选项中至少有一个始终是真实的,那tablename是不是空或空。总是检查你的代码的先决条件,当你将来使用你的代码犯错时,它会为你节省很多麻烦!