我正在创建一个 contentProvider ,并且我希望能够使用单个批处理操作向它发送多个数据库记录(contentValues)以插入或更新到单个表中。
我怎么做?
batchInsert 仅用于插入,但这是否意味着插入已经存在的东西不会做任何事情?
另外,更新操作有没有办法使用特殊约束?例如,我需要忽略主键并根据另外两个唯一的字段进行更新。
我正在创建一个 contentProvider ,并且我希望能够使用单个批处理操作向它发送多个数据库记录(contentValues)以插入或更新到单个表中。
我怎么做?
batchInsert 仅用于插入,但这是否意味着插入已经存在的东西不会做任何事情?
另外,更新操作有没有办法使用特殊约束?例如,我需要忽略主键并根据另外两个唯一的字段进行更新。
“batchInsert 仅用于插入”:这是真的,但您可以在 ContentProvider 中覆盖它以执行 UPSERT(插入/更新),具体取决于传递给 batchInsert 的 URI。
以下是我目前用于对时间序列数据执行批量插入的一些工作代码(诚然,我只是删除了任何阻碍而不是更新的内容,但您可以轻松地将其更改为您自己的目的。)。
还要注意sql事务的使用;这极大地加快了这个过程。
@Override
public int bulkInsert(Uri uri, ContentValues[] values) {
SQLiteDatabase sqlDB = database.getWritableDatabase();
switch (match(uri)) {
case ONEPROGRAMME:
String cid = uri.getLastPathSegment();
int insertCount = 0;
int len = values.length;
if (len > 0) {
long start = values[0].getAsLong(Programme.COLUMN_START);
long end = values[len - 1].getAsLong(Programme.COLUMN_END);
String where = Programme.COLUMN_CHANNEL + "=? AND " + Programme.COLUMN_START + ">=? AND "
+ Programme.COLUMN_END + "<=?";
String[] args = { cid, Long.toString(start), Long.toString(end) };
//TODO use a compiled statement ?
//SQLiteStatement stmt = sqlDB.compileStatement(INSERT)
sqlDB.beginTransaction();
try {
sqlDB.delete(tableName(PROGRAMME_TABLE), where, args);
for (ContentValues row : values) {
if (sqlDB.insert(tableName(PROGRAMME_TABLE), null, row) != -1L) {
insertCount++;
}
}
sqlDB.setTransactionSuccessful();
} finally {
sqlDB.endTransaction();
}
}
if (insertCount > 0)
getContext().getContentResolver().notifyChange(Resolver.PROGRAMME.uri, null);
return insertCount;
default:
throw new UnsupportedOperationException("Unsupported URI: " + uri);
}
}