2012-07-17 86 views
1

我再次運行它有趣的問題,我需要動態構建包含IN條件的SQL查詢。所以我有一個字符串列表,我需要將它們插入我的StringBuilder,由昏迷分隔。在字符串之間添加n-1逗號

所以我的第一個想法是採用一些布爾值來確定我是否應該插入昏迷或不。

builder.append("TABLE.METACODES in ("); 
boolean isFirst = true; 
for(String metaCode : cto.getEntityMetaCodes()) { 
    if(isFirst) { 
     isFirst = false; 
     builder.append("'" + metaCode + "'"); 
    } else { 
     builder.append(", '" + metaCode + "'"); 
    } 
} 
builder.append(")"); 

難道你不會想到更好的解決方案嗎?

回答

1

不使用外部庫,我會做這樣的事情:

builder.append("TABLE.METACODES in ("); 
EntityMetaCodes emc = cto.getEntityMetaCodes(); 
builder.append("'" + emc.remove(0) + "'"); // assuming it's an ArrayList, remove(0) takes out the 
           // first element and moves everything else to the left 
for(String metaCode : emc) { 
    builder.append(", '" + metaCode + "'"); 
} 
builder.append(")"); 
+0

好主意,我最喜歡這個解決方案:) – 2012-07-18 07:43:50

4

您可以使用StringUtils中的join,這會讓最後一個逗號給出您想要的結果。

從文檔:

聯接所提供的陣列的元件到含有元素的提供的列表的單個字符串 。

在列表之前或之後不添加任何分隔符。空分隔符是 ,與空字符串(「」)相同。空數組由 中的空對象或空字符串表示爲空字符串。

StringUtils.join(null, *)    = null 
StringUtils.join([], *)     = "" 
StringUtils.join([null], *)    = "" 
StringUtils.join(["a", "b", "c"], "--") = "a--b--c" 
StringUtils.join(["a", "b", "c"], null) = "abc" 
StringUtils.join(["a", "b", "c"], "") = "abc" 
StringUtils.join([null, "", "a"], ',') = ",,a" 

你可以使用相同的方法:

builder.append("TABLE.METACODES in ('"); 
boolean isFirst = true; 
StringUtils.join(cto.getEntityMetaCodes(),"','"); 
builder.append("')"); 

你需要注意,當集合爲空,因爲這種方法的結果將是一個有效的SQL:TABLE.METACODES in ('')和您的代碼會是無效的:TABLE.METACODES in()

+0

感謝小費,但我們不可惜的使用Apache共享。 – 2012-07-17 08:11:52

+0

如果你不使用,我會建議你用這個方法創建一個Helper類;)也許看一看Apache Commons代碼......它已經被優化了 – 2012-07-17 08:13:42

+0

你可以看看這裏:http://www.docjar .com/html/api/org/apache/commons/lang/StringUtils.java.html行:3370(也許只是提取方法,因爲它是你的幫助類) – 2012-07-17 08:15:43

2

I need to dynamically build SQL query which contatins the IN condition ..不,不,你真的沒有。真的,在很多層面上都很糟糕。現在沒有理由爲SQL查詢操縱字符串,只有當你總是獲得SQL注入攻擊時,纔會讓你進入科技出版社。

Hibernate可以很容易地與集合see here做到這一點,我希望普通的PreparedStatements可以做到這一點,儘管可能你必須手動構建in子句,然後在循環中設置變量 - in這種情況採用弗朗西斯科的方法,但使用佔位符。

+0

我會這樣做,如果我可以,我有我自己的這樣做的原因(我需要使用Oracles分區,所以我不能使用Criteria API,參數可能會有所不同,所以我不能使用NamedQueries) – 2012-07-17 08:09:34

+0

但是,嘿,在這種情況下你是對的,這個參數將永遠存在,我沒有意識到。謝謝 – 2012-07-17 08:11:10

+0

@Petr Hibernate(以及它的一個端口)應該支持分片和合並,所以我認爲它也可以用於oracle分區,但是從來沒有使用過oracle,所以不知道。無論如何,您至少可以使用Francisco的方法構建預備語句,並讓SQL規範化由JDBC驅動程序完成。仍然有點混亂,但給你的安全。 – Voo 2012-07-17 08:12:00

相關問題