tags:

views:

70

answers:

3

I have a java.sql.ResultSet object that I need to update. However the resultset is not updatable. Unfortunately this is a constraint on the particular framework I'm using.

What I'm trying to achieve here is taking data from a database, then manipulating a small amount of the data and finally the data is being written to a CSV file.

At this stage I think my best option is to create a new resultset object and copy the contents of the original resultset into the new one, manipulating the data as I do so.

However, I've hunted high and low on google and don't seem to be able to determine how to do this or whether it's even possible at all.

I'm new to everything Java so any assistance would be gratefully received.

A: 

Do you have to use a record set? How about raw JDBC?

Jeanne Boyarsky
This should have been posted as a comment, not as an answer.
BalusC
Hi thanks for the response. Yes - I have to use a resultset.
Peanut
Sorry. I assume I can't change it now?
Jeanne Boyarsky
+4  A: 

The normal practice would be to map the ResultSet to a List<Entity> where Entity is your own class which contains information about the data represented by a single database row. E.g. User, Person, Address, Product, Order, etcetera, depending on what the table actually contains.

List<Entity> entities = new ArrayList<Entity>();
// ...
while (resultSet.next()) {
    Entity entity = new Entity();
    entity.setId(resultSet.getLong("id"));
    entity.setName(resultSet.getString("name"));
    entity.setValue(resultSet.getInt("value"));
    // ...
    entities.add(entity);
}
// ...
return entities;

Then, you can access, traverse and modify it the usual Java way. Finally, when persisting it back in the DB, use a PreparedStatement to update them in batches in a single go.

String sql = "UPDATE entity SET name = ?, value = ? WHERE id = ?";
// ...
statement = connection.prepareStatement(sql);
for (Entity entity : entities) {
    statement.setString(1, entity.getName());
    statement.setInt(2, entity.getValue());
    statement.setLong(3, entity.getId());
    // ...
    statement.addBatch();
}
statement.executeBatch();
// ...

Note that some DB's have a limit on the batch size. Oracle's JDBC driver has a limit on around 1000 items. You may want to call executeBatch() every 1000 items then. It should be simple using a counter inside the loop.

See also:

BalusC
Hi - thanks for the great response. In this situation - the data is being pull from the db, there will be a small amount of manipulation and then the data is being written to a CSV file.
Peanut
If the manipulation is row-based, then just do it inside the `while` loop and write it immediately as a new line of CSV file. By the way, the average DB ships with CSV export facilities which can do it more efficient than you can ever do in Java. It's unclear which one you're using, so here's just a MySQL based example: `LOAD DATA INFILE`.
BalusC
A: 

Thanks for the responses. In the end I found CachedRowSet which is exactly what I needed. With this I was able to disconnect the resultset object and update it.

What's more, because CachedRowSet implements the ResultSet interface I was still able to pass it to my file generation method which requires an object that implements ResultSet.

Peanut