我的目标
我想批量插入多个记录到sqlite(事务性).
我的问题
我发现android.content.ContentResolver.bulkInsert(..)方法很有趣,但是javadoc说明:
This function make no guarantees about the atomicity of the insertions.
为什么android会提供一种瘫痪的方法?你能说出用于非原子插入的用例吗?我显然会覆盖ContentProvider.bulkInsert(..)以确保自己的原子性,所以我不确定为什么它是这样的短语.
解决方法
我们需要覆盖批量插入方法,如下所示……
- public class Provider extends ContentProvider {
- public static final Uri URI = Uri.parse("content://com.example.android.hoge/");
- @Override
- public String getType(Uri uri) {
- return null;
- }
- @Override
- public boolean onCreate() {
- return false;
- }
- @Override
- public Cursor query(Uri uri,String[] projection,String selection,String[] selectionArgs,String sortOrder) {
- Helper helper = Helper.getInstance(getContext(),null);
- sqliteDatabase sdb = helper.getReadableDatabase();
- Cursor cursor = sdb.query(
- Table.TABLENAME,new String[]{Table.ID,Table.DATA,Table.CREATED},selection,selectionArgs,null,sortOrder,null
- );
- return cursor;
- }
- @Override
- public Uri insert(Uri uri,ContentValues values) {
- Helper helper = Helper.getInstance(getContext(),null);
- sqliteDatabase sdb = helper.getWritableDatabase();
- sdb.insert(Table.TABLENAME,values);
- getContext().getContentResolver().notifyChange(uri,null);
- return uri;
- }
- /**
- * super.bulkInsert is implemented the loop of insert without transaction
- * So we need to override it and implement transaction.
- */
- @Override
- public int bulkInsert(Uri uri,ContentValues[] values) {
- Helper helper = Helper.getInstance(getContext(),null);
- sqliteDatabase sdb = helper.getWritableDatabase();
- sdb.beginTransaction();
- sqliteStatement stmt = sdb.compileStatement(
- "INSERT INTO `" + Table.TABLENAME + "`(`" + Table.DATA + "`,`" + Table.CREATED + "`) VALUES (?,?);"
- );
- int length = values.length;
- for(int i = 0; i < length; i++){
- stmt.bindString(1,values[i].getAsString(Table.DATA));
- stmt.bindLong(2,values[i].getAsLong(Table.CREATED));
- stmt.executeInsert();
- }
- sdb.setTransactionSuccessful();
- sdb.endTransaction();
- return length;
- }
- @Override
- public int update(Uri uri,ContentValues values,String[] selectionArgs) {
- Helper helper = Helper.getInstance(getContext(),null);
- sqliteDatabase sdb = helper.getWritableDatabase();
- int rows = sdb.update(Table.TABLENAME,values,selectionArgs);
- getContext().getContentResolver().notifyChange(uri,null);
- return rows;
- }
- @Override
- public int delete(Uri uri,null);
- sqliteDatabase sdb = helper.getWritableDatabase();
- int rows = sdb.delete(Table.TABLENAME,null);
- return rows;
- }
- private static class Helper extends sqliteOpenHelper {
- static Helper INSTANCE = null;
- private Helper(Context context,CursorFactory factory) {
- super(context,Table.FILENAME,factory,Table.VERSION);
- }
- public static Helper getInstance(Context context,CursorFactory factory) {
- if (INSTANCE == null) {
- INSTANCE = new Helper(context,factory);
- }
- return INSTANCE;
- }
- @Override
- public void onCreate(sqliteDatabase db) {
- db.execsql(
- "CREATE TABLE `" + Table.TABLENAME + "`(" +
- " `" + Table.ID + "` INTEGER PRIMARY KEY AUTOINCREMENT," +
- " `" + Table.CREATED + "` INTEGER," +
- " `" + Table.DATA + "` TEXT" +
- ");"
- );
- }
- @Override
- public void onUpgrade(sqliteDatabase db,int oldVersion,int newVersion) {
- }
- }
- }