2012-05-22 4 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 절을 추가하기 전에 마지막 두 문자를 값에서 잘라냅니다. 선택 사항 ... '패드'기법은 출력을하고 있지만 추가를 실행 취소 할 수없는 경우에도 작동합니다.

+1

깨진. 당신은 if 시체 주위에 중괄호가 필요합니다. –

+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 대신 아파치 코 몬즈을 선호합니다. 나는 아파치 라이브러리가 거대하고 상호 연결되어 있다고 생각하기 때문에이 라이브러리를 선호한다. 여기 아래 내가 당신의 SQL 문자열을 구축 할 방법은 다음과 같습니다

메소드 본문의 시작에 전제 조건은 부울 옵션 중 하나 이상이 항상 사실, 그 TABLENAME이 아니라는 것을 확인하기위한 것입니다
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(); 
    } 

} 

null 또는 비어 있습니다. 코드의 전제 조건을 항상 확인하십시오. 나중에 코드를 사용하여 실수를 범하면 많은 문제를 해결할 수 있습니다!

관련 문제