1

我再次遇到有趣的问题,我需要动态构建包含 IN 条件的 SQL 查询。所以我有字符串列表,我需要将它们插入到我StringBuilder的逗号分隔中。

所以我的第一个想法是使用一些布尔值来确定我是否应该插入昏迷。

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

你能想出更好的解决方案吗?

4

3 回答 3

4

你可以使用joinfrom StringUtils,这会让最后一个逗号给出你想要的一个很好的结果。

从文档:

将提供的数组的元素连接到包含提供的元素列表的单个字符串中。

列表前后不加分隔符。空分隔符与空字符串 ("") 相同。数组中的空对象或空字符串由空字符串表示。

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

于 2012-07-17T08:03:45.790 回答
2

I need to dynamically build SQL query which contatins the IN condition..不,不,你真的没有。真的,这在很多层面上都是可怕的。现在没有理由为 SQL 查询操作字符串,只有当你总是遇到 SQL 注入漏洞时,你才会出现在技术媒体上。

Hibernate 可以通过集合(参见此处)轻松地做到这一点,我希望普通的 PreparedStatements 也能做到这一点,尽管您可能必须手动构建 in 子句,然后在循环中设置变量 - 在这种情况下采取弗朗西斯科的方法,但使用占位符代替。

于 2012-07-17T08:06:49.930 回答
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(")");
于 2012-07-17T08:23:25.800 回答