Android数据库的批处理操作(以添加联系人为例)

Batch operations

Data rows can be inserted/updated/deleted using the traditional insert(Uri, ContentValues), update(Uri, ContentValues, String, String[]) and delete(Uri, String, String[]) methods, however the newer mechanism based on a batch of ContentProviderOperation will prove to be a better choice in almost all cases. All operations in a batch are executed in a single transaction, which ensures that the phone-side and server-side state of a raw contact are always consistent. Also, the batch-based approach is far more efficient: not only are the database operations faster when executed in a single transaction, but also sending a batch of commands to the content provider saves a lot of time on context switching between your process and the process in which the content provider runs.

The flip side of using batched operations is that a large batch may lock up the database for a long time preventing other applications from accessing data and potentially causing ANRs ("Application Not Responding" dialogs.)

To avoid such lockups of the database, make sure to insert "yield points" in the batch. A yield point indicates to the content provider that before executing the next operation it can commit the changes that have already been made, yield to other requests, open another transaction and continue processing operations. A yield point will not automatically commit the transaction, but only if there is another request waiting on the database. Normally a sync adapter should insert a yield point at the beginning of each raw contact operation sequence in the batch. See withYieldAllowed(boolean).

Operations

Insert

An individual data row can be inserted using the traditional insert(Uri, ContentValues) method. Multiple rows should always be inserted as a batch.

An example of a traditional insert:

 ContentValues values = new ContentValues();
 values.put(Data.RAW_CONTACT_ID, rawContactId);
 values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
 values.put(Phone.NUMBER, "1-800-GOOG-411");
 values.put(Phone.TYPE, Phone.TYPE_CUSTOM);
 values.put(Phone.LABEL, "free directory assistance");
 Uri dataUri = getContentResolver().insert(Data.CONTENT_URI, values);
 

The same done using ContentProviderOperations:

 ArrayList<ContentProviderOperation> ops =
          new ArrayList<ContentProviderOperation>();

 ops.add(ContentProviderOperation.newInsert(Data.CONTENT_URI)
          .withValue(Data.RAW_CONTACT_ID, rawContactId)
          .withValue(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE)
          .withValue(Phone.NUMBER, "1-800-GOOG-411")
          .withValue(Phone.TYPE, Phone.TYPE_CUSTOM)
          .withValue(Phone.LABEL, "free directory assistance")
          .build());
 getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
 
Update

Just as with insert, update can be done incrementally or as a batch, the batch mode being the preferred method:

 ArrayList<ContentProviderOperation> ops =
          new ArrayList<ContentProviderOperation>();

 ops.add(ContentProviderOperation.newUpdate(Data.CONTENT_URI)
          .withSelection(Data._ID + "=?", new String[]{String.valueOf(dataId)})
          .withValue(Email.DATA, "somebody@android.com")
          .build());
 getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
 
Delete

Just as with insert and update, deletion can be done either using the delete(Uri, String, String[]) method or using a ContentProviderOperation:

 ArrayList<ContentProviderOperation> ops =
          new ArrayList<ContentProviderOperation>();

 ops.add(ContentProviderOperation.newDelete(Data.CONTENT_URI)
          .withSelection(Data._ID + "=?", new String[]{String.valueOf(dataId)})
          .build());
 getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
 
Query
Finding all Data of a given type for a given contact
 Cursor c = getContentResolver().query(Data.CONTENT_URI,
          new String[] {Data._ID, Phone.NUMBER, Phone.TYPE, Phone.LABEL},
          Data.CONTACT_ID + "=?" + " AND "
                  + Data.MIMETYPE + "='" + Phone.CONTENT_ITEM_TYPE + "'",
          new String[] {String.valueOf(contactId)}, null);
 
Finding all Data of a given type for a given raw contact
 Cursor c = getContentResolver().query(Data.CONTENT_URI,
          new String[] {Data._ID, Phone.NUMBER, Phone.TYPE, Phone.LABEL},
          Data.RAW_CONTACT_ID + "=?" + " AND "
                  + Data.MIMETYPE + "='" + Phone.CONTENT_ITEM_TYPE + "'",
          new String[] {String.valueOf(rawContactId)}, null);
 
Finding all Data for a given raw contact
Most sync adapters will want to read all data rows for a raw contact along with the raw contact itself. For that you should use the ContactsContract.RawContactsEntity. See also ContactsContract.RawContacts.

以添加联系人为例:

  1. protected void createContactEntry() {  
  2.      
  3.     ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();  
  4.     ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)  
  5.             .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, mSelectedAccount.getType())  
  6.             .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, mSelectedAccount.getName())  
  7.             .build());  
  8.     ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)  
  9.             .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)  
  10.             .withValue(ContactsContract.Data.MIMETYPE,  
  11.                     ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)  
  12.             .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, "小明")  
  13.             .build());  
  14.     ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)  
  15.             .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)  
  16.             .withValue(ContactsContract.Data.MIMETYPE,  
  17.                     ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)  
  18.             .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, "10086")  
  19.             .withValue(ContactsContract.CommonDataKinds.Phone.TYPE, "1")  
  20.             .build());  
  21.     ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)  
  22.             .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)  
  23.             .withValue(ContactsContract.Data.MIMETYPE,  
  24.                     ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)  
  25.             .withValue(ContactsContract.CommonDataKinds.Email.DATA, "google@sina.com")  
  26.             .withValue(ContactsContract.CommonDataKinds.Email.TYPE, "1")  
  27.             .build());  
  28.   
  29.     try {  
  30.         getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);  
  31.     } catch (Exception e) {  
  32.         Log.e(TAG, "Exceptoin encoutered while inserting contact: " + e);  
  33.     }  
  34. }  

 

这里withValueBackReference("column","index");第一个参数对应于数据库中的列,第二个参数代表着回引的值。这个比较抽象,也就是说,批量操作数据库时,index表示ArrayList<ContentProviderOperation> ops 这个操作列表中,第几个操作返回结果的id或是数量。

 

例如:上面的代码withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0);这个表示将ContactsContract.Data.RAW_CONTACT_ID的值设为以下插入操作执行完毕后返回的uri中Id的值。

  1. ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI) .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, mSelectedAccount.getType()) .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, mSelectedAccount.getName()) .build()  


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android中进行数据库操作的步骤如下: 1. 创建一个自定义的类,继承SQLiteOpenHelper类,并实现onCreate()和onUpgrade()方法。在onCreate()方法中,通过执行SQL语句创建表格。例如,可以使用execSQL()方法执行CREATE TABLE语句来创建表格。\[3\] 2. 在自定义的SQLiteOpenHelper类中,重写onOpen()方法,可以在该方法中进行一些数据库打开时的操作。\[3\] 3. 在需要进行数据库操作的地方,创建一个SQLiteOpenHelper的实例,并调用getWritableDatabase()或getReadableDatabase()方法获取一个可写或可读的数据库对象。\[3\] 4. 使用获取到的数据库对象,可以进行插入、查询、更新和删除等数据库操作。例如,可以使用execSQL()方法执行SQL语句来插入、更新或删除数据。\[1\] 5. 在使用完数据库后,记得调用close()方法关闭数据库连接,释放资源。\[3\] 综上所述,Android数据库操作的步骤包括创建自定义的SQLiteOpenHelper类、实现数据库的创建和升级方法、获取数据库对象、执行数据库操作、关闭数据库连接。 #### 引用[.reference_title] - *1* *3* [Android数据库操作](https://blog.csdn.net/weixin_43244265/article/details/107871897)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Android 连接MySql数据库步骤](https://blog.csdn.net/m0_62321937/article/details/129905218)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值