2012-07-17 74 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

相关问题