У меня есть пользовательский Android ContentProvider
, который хранит и извлекает данные из базы данных SQLite.
Предположим, что в одной из таблиц БД есть столбец _ID
, столбец NAME
и такой контент:
|==========|==========|
| _ID | NAME |
|==========|==========|
| 1 | d1 |
| 2 | d2 |
| 3 | d3 |
| 4 | d4 |
|==========|==========|
Эта БД SQLite синхронизируется с удаленной базой данных, и новые данные периодически выбираются по сети.
Возможные операции над таблицей:
- Существующие строки могут быть удалены
- Можно добавить новые строки
- Столбец NAME существующих строк можно изменить
Теперь давайте предположим, что все возможные операции выполняются одновременно, и после извлечения некоторых актуальных данных с удаленного сервера новое содержимое этой таблицы должно быть установлено следующим образом:
|==========|==========|
| _ID | NAME |
|==========|==========|
| 1 | d7 |
| 3 | d3 |
| 4 | d6 |
| 5 | d5 |
|==========|==========|
Для этого может быть два разных подхода:
- Запросите базу данных и проверьте все существующие строки, чтобы увидеть, нужно ли их обновлять, затем добавьте все новые строки и удалите все пропущенные строки - хотя этот метод может быть немного сложным, если мы хотим обновить базу данных с нумерацией страниц подход, а не с одной сетевой выборки
- Удалите всю таблицу с помощью одной * SQL-команды
DELETE
, а затем добавьте все строки, полученные с сервера
В Android в настоящее время я реализую второй метод с пакетными операциями , чтобы максимизировать производительность:
final ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>();
// with this URI, the content provider deletes all rows
operations.add(ContentProviderOperation.newDelete(Users.CONTENT_URI).build());
final ContentValues values = new ContentValues();
values.put(ID_COLUMN, 1);
values.put(NAME_COLUMN, "d7");
values.put(ID_COLUMN, 3);
values.put(NAME_COLUMN, "d3");
values.put(ID_COLUMN, 4);
values.put(NAME_COLUMN, "d6");
values.put(ID_COLUMN, 5);
values.put(NAME_COLUMN, "d5");
operations.add(ContentProviderOperation.newInsert(Users.CONTENT_URI).withValues(values).build());
getApplicationContext().getContentResolver().applyBatch(MyContentProvider.AUTHORITY, operations);
Является ли это лучшим подходом, или метод 1 (или какой-либо другой метод) будет лучше с точки зрения производительности?
РЕДАКТИРОВАТЬ: например, при подходе 2 переопределенный ContentProvider#bulkInsert
, который использует транзакции базы данных, может значительно ускорить операцию пакетной вставки: см. этот вопрос .