Inserting multiple rows into Sqlite database with Content Providers

I have just found a draft of this post. I know this is a bit outdated but I think this might provide some value to someone still using Content Providers.

So, how can you insert multiple rows into the database at one using SQLite with ContentProvider?

Many separate inserts

Naive approach would be similar to this:

for (int i = 0; i < list.size(); i++) {
    Book book = list.get(i);
    ContentValues cv = getContentValues(book);
    cr.insert(CONTENT_URI, cv);
}

Insert will will insert one row and return it’s row id or -1 if error occurred.
But this approach has several faults. It is slow. There is issue of consistency. You probably want all data to be inserted or none at all, if there is some failure. But here some data might get inserted and some not. And so if an operation is repeated later, duplication might occur. Also, if there are attached observers to data such as Cursors, they will be called multiple times and possibly lag UI.

Bulk insert

ContentValues[] values = new ContentValues[list.size()];
for (int i = 0; i < list.size(); i++) {
    Book book = list.get(i);
    ContentValues cv = getContentValues(book);
    values[i] = cv;
}
cr.bulkInsert(CONTENT_URI, values);

Bulk insert returns number of newly created rows. Bulk insert will save you time. But it won’t save you from possible consistency problems.

This function make no guarantees about the atomicity of the insertions.

To get around this, you can override this function or use applyBatch instead.

Apply batch

Apply batch has different syntax but has similar use as bulkInsert. You have to create ArrayList of Content Provider Operations:

ArrayList<ContentProviderOperation> batch = new ArrayList<ContentProviderOperation>();
for (int i = 0; i < list.size(); i++) {
    Book book = list.get(i);
    ContentValues cv = getContentValues(book);
    ContentProviderOperation cpo = ContentProviderOperation.newInsert(CONTENT_URI)
            .withValues(cv)
            .build();
    batch.add(cpo);
}
cr.applyBatch(DatabaseProvider.AUTHORITY, batch);

These operations can be a combination of inserts, updates and deletions. Apply batch run in transaction so unline bulkInsert it will succeed or fail and data consistency will be mantained. This function returns array of ContentProviderResult, that includes Uri of inserted item or count of updated or deleted items.