Обновить данные в БД

Необходимо получить пользователя из БД по имени и фамилии и обновить его данные. Я написал метод для обновления данных

private static void UpdateUser(String Name,String Surname,String data) throws SQLException {

        String query = "update users set name=?,surname=?,date=?,email=?,socials=? where name=? and surname=?";
        PreparedStatement statement = dbWorker.getConnection().prepareStatement(query);
        statement.setString(1,Name);
        statement.setString(2,Surname);

        User updatedUser = gson.fromJson(data,User.class);
        User userToUpdate = ReadUser(Name,Surname);

        if(updatedUser.getName() != null){
            userToUpdate.setName(updatedUser.getName());
            statement.setString(1, userToUpdate.getName());
        }
        if(updatedUser.getSurname() != null){
            userToUpdate.setSurname(updatedUser.getSurname());
            statement.setString(2, userToUpdate.getSurname());
        }
        if(updatedUser.getDate() != null){
            userToUpdate.setDate(updatedUser.getDate());
            statement.setString(3,updatedUser.getDate());
        }
        if(updatedUser.getEmail() != null){
            userToUpdate.setEmail(updatedUser.getEmail());
            statement.setString(4,updatedUser.getEmail());
        }
        if(updatedUser.getSocials() != null){
            userToUpdate.setSocials(updatedUser.getSocials());
            statement.setString(5, updatedUser.getSocials());
        }
    }

При запуске получаю ошибку синтаксиса SQL You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '? and surname = ?' at line 1. Мне кажется что данный метод можно реализовать проще. Подскажите как это сделать? Или хотя бы почему возникается такая ошибка? Использую БД MySQL.


Ответы (1 шт):

Автор решения: Alexandr
  1. Вы пытаетесь задать параметры под одним и тем же индексом. У Вас в запросе 7 параметров, а значения Вы задаете с индексами 1-5
  2. Если Вы хотите чтобы только определенные поля были изменены, то Вам необходимо и запрос генерировать динамически.

Вот примерный код с динамическим запросом:

private static void updateUser(
        String name,
        String surname,
        String data) throws SQLException {
    User updatedUser = gson.fromJson(data, User.class);
    User userToUpdate = ReadUser(name, surname);

    Map<String, Object> fields = new HashMap<>();
    if (updatedUser.getName() != null) {
        userToUpdate.setName(updatedUser.getName());
        fields.put("name", userToUpdate.getName());
    }
    if (updatedUser.getSurname() != null) {
        userToUpdate.setSurname(updatedUser.getSurname());
        fields.put("surname", userToUpdate.getSurname());
    }
    if (updatedUser.getDate() != null) {
        userToUpdate.setDate(updatedUser.getDate());
        fields.put("date", updatedUser.getDate());
    }
    if (updatedUser.getEmail() != null) {
        userToUpdate.setEmail(updatedUser.getEmail());
        fields.put("email", updatedUser.getEmail());
    }
    if (updatedUser.getSocials() != null) {
        userToUpdate.setSocials(updatedUser.getSocials());
        fields.put("socials", updatedUser.getSocials());
    }
    StringBuilder query =
            new StringBuilder("update users set");
    int index = 1;
    List<Object> parameters = new ArrayList<>();
    for (String fieldName : fields.keySet()) {
        Object fieldValue = fields.get(fieldName);
        if (fieldValue != null) {
            if (index++ == 1){
                query.append(" ").append(fieldName).append("=?");
            } else {
                query.append(", ").append(fieldName).append("=?");
            }
            parameters.add(fieldValue);
        }
    }
    query.append(" where name=? and surname=?");
    parameters.add(name);
    parameters.add(surname);

    PreparedStatement statement =
            dbWorker.getConnection().prepareStatement(
                    query.toString());
    for (int i = 0; i < parameters.size(); i++) {
        statement.setObject(i, parameters.get(i));
    }
}
→ Ссылка