如何实现一个具有多个表的内容提供程序? [英] How to implement a content provider with more than one table?

查看:72
本文介绍了如何实现一个具有多个表的内容提供程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新:看着"vnd.android.cursor.dir/vnd.google.note""vnd.android.cursor.item/vnd.google.note"在我看来,光标似乎是在一张桌子上.

update: looking at "vnd.android.cursor.dir/vnd.google.note" and "vnd.android.cursor.item/vnd.google.note" it seemed to me as though the cursor was for one table.

在示例中,似乎内容提供者旨在使用一个表.我确实知道如何在sqlite中使用多个表,但是在我看来,内容提供者似乎是要从一个表中选择一行或多行.

From the examples it appears as though content provider were designed to work with one table. I do know how to use multiple tables in sqlite but it seems to me that the content provider seems to be about picking one row or multiple rows from one table.

请参见 http://developer.android.com/guide/topics/providers/content-provider-creating.html

另外,请参阅adt-bundle-windows-x86-20131030 \ sdk \ samples \ android-19 \ legacy \ NotePad \ src \ com \ example \ android \ notepad

Also, see the notepad sample in adt-bundle-windows-x86-20131030\sdk\samples\android-19\legacy\NotePad\src\com\example\android\notepad

假设我想按主题记录笔记.

Suppose I want to have notes by topic.

我希望有一个主题表,该表的_id和Title_text列. 我想使用带有_id列和外键Topic_id和Note_text的Notes表.

I would like to have a Topics table with columns _id and Title_text. I would like to have the Notes table with columns _id and foreign key Topic_id and Note_text.

一个人如何设计主题和注释?

How would one design the Topics and Notes?

但是,从Notes样本,内容提供商的内容URI和文档来看,似乎有多个相关表是事后的想法,对我而言并不明显.

But looking at the Notes sample, the content URIs and docs on content providers, it appears as though having multiple related tables is an afterthought and is not obvious to me.

从NotepadProvider.java,Notepad.java:

from NotepadProvider.java, Notepad.java:

    public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.google.note";

        /**
         * The MIME type of a {@link #CONTENT_URI} sub-directory of a single
         * note.
         */
        public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.google.note";

                public static final Uri CONTENT_ID_URI_BASE
            = Uri.parse(SCHEME + AUTHORITY + PATH_NOTE_ID);

        /**
         * The content URI match pattern for a single note, specified by its ID. Use this to match
         * incoming URIs or to construct an Intent.
         */
        public static final Uri CONTENT_ID_URI_PATTERN
            = Uri.parse(SCHEME + AUTHORITY + PATH_NOTE_ID + "/#");



               @Override
   public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
           String sortOrder) {
            ...
                   switch (sUriMatcher.match(uri)) {

           // If the incoming URI is for notes, chooses the Notes projection
           case NOTES:
               qb.setProjectionMap(sNotesProjectionMap);
               break;

           /* If the incoming URI is for a single note identified by its ID, chooses the
            * note ID projection, and appends "_ID = <noteID>" to the where clause, so that
            * it selects that single note
            */
           case NOTE_ID:
               qb.setProjectionMap(sNotesProjectionMap);
               qb.appendWhere(
                   NotePad.Notes._ID +    // the name of the ID column
                   "=" +
                   // the position of the note ID itself in the incoming URI
                   uri.getPathSegments().get(NotePad.Notes.NOTE_ID_PATH_POSITION));
               break;

推荐答案

在创建ContentProvider时,期望其他应用程序将使用您的数据库,这意味着其他对您的数据库一无所知的人方案.为了使事情变得简单,您可以创建并记录URI:

When creating a ContentProvider, the expectation is that other apps are going to use your database, and with that I mean other people who know nothing about your database scheme. To make things easy for them, you create and document your URIs:

要访问所有图书

content://org.example.bookprovider/books

通过ID访问图书

content://org.example.bookprovider/books/#

按作者姓名访问图书

content://org.example.bookprovider/books/author

根据您的需要创建任意数量的URI.这样,提供者的用户就可以非常轻松地访问您的数据库信息,这也许就是为什么您会觉得提供者被设计为可以使用一个表数据库的感觉,但是没有,内部是完成工作的地方.

Create as many URIs as you need, that’s up to you. This way the user of your Provider can very easily access your database info, and maybe that’s why you are getting the impression that the Provider is designed to work with one table databases, but no, internally is where the work is done.

在ContentProvider子类中,可以使用UriMatcher标识将要传递到ContentProvider方法的那些不同的URI(queryinsertupdatedelete).如果Uri所请求的数据存储在多个表中,则实际上可以使用

In your ContentProvider subclass, you can use a UriMatcher to identify those different URIs that are going to be passed to your ContentProvider methods (query, insert, update, delete). If the data the Uri is requesting is stored in several tables, you can actually do the JOINs and GROUP BYs or whatever you need with SQLiteQueryBuilder , e.g.

public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
    SQLiteQueryBuilder mQueryBuilder = new SQLiteQueryBuilder();
    . . .   
    String Joins = " t1 INNER JOIN table2 t2 ON t2._id = t1._id"
    + " INNER JOIN table3 t3 ON t3._id = t1._id";

    switch (mUriMatcher.match(uri)) {
        case DATA_COLLECTION_URI:
            mQueryBuilder.setTables(YourDataContract.TABLE1_NAME + Joins);
            mQueryBuilder.setProjectionMap(. . .);
            break;
        case SINGLE_DATA_URI:
            mQueryBuilder.setTables(YourDataContract.TABLE1_NAME + Joins);
            mQueryBuilder.setProjectionMap(. . .);
            mQueryBuilder.appendWhere(Table1._ID + "=" + uri.getPathSegments().get(1));
            break;
        case . . .
        default:
            throw new IllegalArgumentException("Unknown URI " + uri);
    }
    . . .
    SQLiteDatabase db = mOpenHelper.getReadableDatabase();
    Cursor c = mQueryBuilder.query(db, projection, selection, selectionArgs, groupBy, having, orderBy);
    return c;
}

希望有帮助.

这篇关于如何实现一个具有多个表的内容提供程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆