使用ContentProvider插入多个表

Gal*_*aim 4 android android-contentresolver android-contentprovider android-sqlite

我正在实现一个PRIVATE ContentProvider,它有几个关系表(一对多,多对多).在我当前的实现中,所有表都可以通过URI访问.如何简化界面,以便URI不必访问内部的"通过"表?

例如,我有一个POSTS表,每个POST通过TAGGINGS表有很多TAGS.我想只与POSTS URI进行交互,并在内部进行"私有"工作ContentProvider.

为了query简单地返回带有连接表的游标,但我该怎么做insert呢?是bulkInsert我应该到什么?

bie*_*eux 7

这是一个限制ContentProvider.如果您没有将数据公开给其他应用程序,则可以使用自定义数据库适配器实现,方法和查询直接满足您的要求.

bulkInsert()在这种情况下不会有帮助,因为它一次只将行插入一个表中.但是看看ContentProvider.applyBatch()方法和ContentProviderOperation,ContentProviderOperation.Builder类(您可能需要withValueBackReference()一对多插入).

这些链接应该可以帮助您了解如何使用它们:

http://www.grokkingandroid.com/better-performance-with-contentprovideroperation/ http://www.grokkingandroid.com/androids-contentprovideroperation-withbackreference-explained/ withValueBackReference的语义是什么?

但请注意,使用ContentProviderOperationbulkInsert()一次插入多行要慢得多,因为Uri每次执行操作时它都会解析(字符串比较).这样做你仍然需要公开Uri以插入子表.

如果您决定使用applyBatch(),请在提供程序中覆盖它,以便它在一个事务中执行所有操作,这样您可以保持数据的一致性并加快数据库操作:

@Override
public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
        throws OperationApplicationException {
    final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
    db.beginTransaction();
    try {
        ContentProviderResult[] results = super.applyBatch(operations);
        db.setTransactionSuccessful();
        return results;
    } finally {
        db.endTransaction();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 你可以在这里找到许多使用CP vs db adapter的优缺点答案.在某些情况下,坚持使用CP是很好的,例如CursorLoader仅适用于CP,CP使得从服务和活动访问db非常容易,因为它为您处理线程安全.另一方面,CP在您的应用程序中添加了另一个消耗更多资源的层,复杂的查询也可能存在问题(仅基本查询,插入,更新,删除方法,输入数据仅作为ContentValue). (2认同)