Есть коллекция с множеством объектов. Коллекция выводится в таблицу. Пользователь в оффлайне может добавлять и удалять записи, а также обновлять полученные ранее через SELECY * FROM ...
Хочу реализовать функцию "Сохранить Все", при которой программа проходилась бы по все коллекции и обновляла записи в БД, если они существуют, и добавляла бы новые, если их нет.
Пришёл к следующему решению со стороны Java:
@Override
public void updateAll(List<User> users)
{
//online
Connection connection = null;
PreparedStatement statement = null;
try
{
connection = Database.getInstance().getConnection();
connection.setAutoCommit(false);
for (User user : users)
{
statement = connection.prepareStatement(""); //вот тут правильно составить запрос
statement.execute();
}
connection.commit();
}
catch (SQLException ex)
{
Log.error("Unable to updateAll users. " + ex.getMessage());
}
finally
{
Database.closeQuietly(statement);
Database.closeQuietly(connection);
}
}
Посколько содержимое таблицы могли обновить значительно, а сохранить надо быстро, отключаю автокоммит и буду отправлять одной большой пачкой запросов за раз.
Теперь о самом запросе... На просторах известного сайта нашёл, что PostgreSQL поддерживает нужный мне функционал в виде:
INSERT INTO the_table (id, column_1, column_2)
VALUES (1, 'A', 'X'), (2, 'B', 'Y'), (3, 'C', 'Z')
ON CONFLICT (id) DO UPDATE
SET column_1 = excluded.column_1,
column_2 = excluded.column_2;
Сразу возникло несколько вопросов
- Теперь мне это надо поместить в PreparedStatement. Как безопасно воткнут данные в INSERT часть запроса я знаю, а вот как быть с update частью, где надо перечислить все данные в скобках - кроме конкатенации в голову ничего не пришло, но это не путь джедая.
- Поскольку мне чаще надо обновлять данные, чем вставлять новые, корректно ли использовать INSERT часть как основу, а уже потом выполнять UPDATE, если существует? Может я зря заморачиваюсь, а может оно реально скажется на скорости? Поменять местами? Но как?