首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用MessageFormat生成where子句

使用MessageFormat生成where子句
EN

Stack Overflow用户
提问于 2020-03-03 19:17:01
回答 1查看 67关注 0票数 0

我希望使用MessageFormat生成SQL,以便许多用户可以使用相同的字符串,并且他们只需传递where子句参数。

例如,我想要select * from user where name='John‘和age=15 and area='JStreet’

我可以使用MessageFormat.format(select * from user where {0}={1} and {2}={3} and {4}={5},"name","'John'","age","15","area","'JStreet'")

但我希望它是动态的。这意味着我在{0}-{5}之前是有界的,如果我需要添加更多的AND条件怎么办。我该怎么做呢?

EN

回答 1

Stack Overflow用户

发布于 2020-03-03 20:14:01

不要让用户将列名指定为字符串。这使得您的代码很容易被破坏,并使您面临一个非常常见且危险的安全漏洞,称为SQL注入。我知道你说这只是“内部使用”,但员工/学生可能是黑客,总有可能有人想要造成伤害。

相反,应将列表示为枚举值。我假设user表的列是固定的,因此您可以在枚举中对它们进行硬编码:

代码语言:javascript
复制
public enum UserField {
    NAME,
    AGE,
    AREA
}

正如其他人提到的,在使用来自最终用户或未知代码的值时,请始终使用PreparedStatement。现在您可以使用枚举来构建该PreparedStatement:

代码语言:javascript
复制
public PreparedStatement createStatement(Map<UserField, ?> values,
                                         Connection conn)
throws SQLException {

    Collection<String> tests = new ArrayList<>(values.size());
    for (UserField field : values.keySet()) {
        tests.add(field.name().toLowerCase() + "=?");
    }

    String sql;
    if (tests.isEmpty()) {
        sql = "select * from user";
    } else {
        sql = "select * from user where " + String.join(" and ", tests);
    }

    PreparedStatement statement = conn.prepareStatement(sql);

    int index = 0;
    for (Object value : values) {
        statement.setObject(++index, value);
    }

    return statement;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60506046

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档