Генерация предложения where с использованием MessageFormat - PullRequest
0 голосов
/ 03 марта 2020

Я хочу сгенерировать SQL с помощью MessageFormat, чтобы многие пользователи могли использовать одну и ту же строку, и им просто нужно передать аргументы where.

например, я хочу выбрать * у пользователя, где name = 'John 'and age = 15 and area =' JStreet '

Я могу сделать это с помощью MessageFormat.format (выберите * у пользователя, где {0} = {1} и {2} = {3} и {4} = {5}, "name", "John", "age", "15", "area", "JStreet" ")

Но я хочу это динамически c. Значит, здесь я ограничен до {0} - {5}, что если мне нужно добавить еще условия AND. Как я могу это сделать?

1 Ответ

0 голосов
/ 03 марта 2020

Не позволяйте пользователю указывать имена столбцов в виде строк. Это делает ваш код легко взломанным и открывает вам очень распространенную и опасную уязвимость безопасности, известную как SQL инъекция. Я знаю, что вы сказали, что это только «для внутреннего использования», но сотрудники / студенты могут быть хакерами, и всегда есть вероятность, что кто-то может причинить вред.

Вместо этого представьте столбцы в виде значений перечисления. Я предполагаю, что столбцы таблицы user являются фиксированными, поэтому их можно жестко закодировать в перечислении:

public enum UserField {
    NAME,
    AGE,
    AREA
}

Как уже упоминали другие, всегда используйте PreparedStatement при использовании значений от конечных пользователей. или из неизвестного кода. Теперь вы можете использовать перечисления для построения этого PreparedStatement:

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;
}
...