如何实现具有多个表的内容提供程序?

lik*_*udo 1 android android-contentprovider

更新:在寻找"vnd.android.cursor.dir/vnd.google.note""vnd.android.cursor.item/vnd.google.note"在我看来,就好像光标是为一个表.

从示例中可以看出内容提供程序设计为使用一个表.我知道如何在sqlite中使用多个表,但在我看来,内容提供者似乎是从一个表中选择一行或多行.

请参阅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中的记事本示例

假设我想按主题发表评论.

我想要一个包含_id和Title_text列的主题表.我想让Notes表包含列_id和外键Topic_id和Note_text.

如何设计主题和注释?

但是看看Notes示例,内容提供商上的内容URI和文档,看起来好像有多个相关的表是事后的想法,对我来说并不明显.

来自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;
Run Code Online (Sandbox Code Playgroud)

ILo*_*cho 10

在创建a时ContentProvider,期望其他应用程序将使用您的数据库,我的意思是其他人对您的数据库方案一无所知.为了方便他们,您可以创建并记录您的URI:

访问所有书籍

content://org.example.bookprovider/books
Run Code Online (Sandbox Code Playgroud)

通过id访问书籍

content://org.example.bookprovider/books/#
Run Code Online (Sandbox Code Playgroud)

按作者姓名访问图书

content://org.example.bookprovider/books/author
Run Code Online (Sandbox Code Playgroud)

根据需要创建尽可能多的URI,这取决于您.这样,您的提供商的用户可以非常轻松地访问您的数据库信息,也许这就是为什么您会得到供应商旨在使用一个表数据库的印象,但不是,内部是工作完成的地方.

在您的ContentProvider的子类,你可以使用UriMatcher,以确定将要传递给你的ContentProvider方法(这些不同的URI query,insert,update,delete).如果Uri请求的数据存储在多个表中,您实际上可以使用SQLiteQueryBuilder执行JOINs和GROUP BYs或任何需要的操作,例如

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;
}
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你.