How to implement a content provider with more than one table?

后端 未结 3 1940
傲寒
傲寒 2021-02-06 19:29

update: looking at \"vnd.android.cursor.dir/vnd.google.note\" and \"vnd.android.cursor.item/vnd.google.note\" it seemed to me as thoug

3条回答
  •  误落风尘
    2021-02-06 20:17

    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:

    To access all the books

    content://org.example.bookprovider/books
    

    to access books by id

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

    to access books by author name

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

    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.

    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;
    }
    

    Hope it helps.

提交回复
热议问题