There is a collection with many objects. The collection is displayed in a table. The user is offline can add and delete records, as well as update the previously received via SELECT * FROM ...
I want to implement the function "Save All", in which the program would go through all the collections and update the records in the database, if they exist, and add new ones if they do not exist.
Came to the following solution (java side):
@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(""); //THIS IS WHERE A CORRECT QUERY SHOULD BE CREATED
statement.execute();
}
connection.commit();
}
catch (SQLException ex)
{
Log.error("Unable to updateAll users. " + ex.getMessage());
}
finally
{
Database.closeQuietly(statement);
Database.closeQuietly(connection);
}
}
Since the contents of the table could be updated significantly, but it’s necessary to save quickly, I disable the auto-commit and send one large batch of requests at a time.
Now about the request itself ... I found that PostgreSQL supports the functionality I need:
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;
Immediately a few questions arose:
- Now I need to put this in PreparedStatement. I know how to safely insert the data in the INSERT part of the request, but what about the UPDATE part, where you need to list all the data in brackets - except string concatenation, nothing came to mind, but as far as I know, this is not the Jedi way.
- Since I need to update data more often than insert new ones, is it correct to use the INSERT part as a basis, and only then execute UPDATE if it exists? Maybe I should not bother in vain, and maybe it will really affect the speed? Swap? But how?