ContentProvider的有多个表多个、ContentProvider

2023-09-06 00:22:25 作者:软软

我想实现一个的ContentProvider 的操纵多个表。以下是我试过到目前为止。我写了一个Java 接口的再presents CRUD操作,每个表应在其CRUD类中实现。

I want to implement a ContentProvider that manipulates multiple tables. Here is what I tried so far. I wrote a Java Interface that represents the CRUD operations that every table should implement in its CRUD class.

public interface CRUDHandler {
    //UPDATE
    int update(Uri uri, ContentValues values, String selection,String[] selectionArgs);
    //READ
    Cursor query(Uri uri, String[] projection, String selection,String[] selectionArgs, String sortOrder) ;
    //CREATE
    Uri insert(Uri uri, ContentValues values);
    //DELETE
    int delete(Uri uri, String selection, String[] selectionArgs);
    //get Mime type
    String getType(Uri uri);
}

然后我写了摘要 定义了一个静态 UriMatcher 的ContentProvider 让每个扩展类这个类应该增加其乌里标识,并规定在接口中的每个方法的实现。

Then I wrote an abstract class that defines a static UriMatcher for the ContentProvider so each class that extends this class should add its Uri that identifies it and provide an implementation for each method in interface.

类看起来是这样的:

public abstract class  ApplicationCRUD  implements CRUDHandler{

    public static final UriMatcher sUriMatcher;

    static {
        sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
    }
}

另外,我创建了一个类的每个扩展这个类,并添加了乌里的表 UriMatcher 从抽象类。

Further, I created a class for each table that extends this class and adds its Uri's to the UriMatcher from the abstract class.

下面是一个例子:

public class Table1CRUD extends ApplicationCRUD {
    //Setup Projection Map for Table1 
        private static HashMap<String , String>sTable1ProjectionMap;
        static {
            sTable1ProjectionMap.put(ApplicationProviderMetaData.Table1MetaData._ID, ApplicationProviderMetaData.Table1MetaData.TABLE_NAME+"."+ApplicationProviderMetaData.Table1MetaData._ID);
            sTable1ProjectionMap.put(ApplicationProviderMetaData.Table1MetaData.COL1, ApplicationProviderMetaData.Table1MetaData.TABLE_NAME+"."+ApplicationProviderMetaData.Table1MetaData.COL1);
            sTable1ProjectionMap.put(ApplicationProviderMetaData.Table1MetaData.COL2, ApplicationProviderMetaData.Table1MetaData.TABLE_NAME+"."+ApplicationProviderMetaData.Table1MetaData.COL2);
        }

        public static final int INCOMING_SINGLE_URI_INDICATOR = 5;
        public static final int INCOMING_COLLECTION_URI_INIDICATOR = 6;
    static {
        //standard URI 
        sUriMatcher.addURI(ApplicationProviderMetaData.AUTHORITY, "t1", INCOMING_COLLECTION_URI_INIDICATOR);
        sUriMatcher.addURI(ApplicationProviderMetaData.AUTHORITY, "t1/#", INCOMING_SINGLE_URI_INDICATOR);
        //here add your custom URI 

    }
    @Override
    public int update(Uri uri, ContentValues values, String selection,
            String[] selectionArgs) {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public String getType(Uri uri) {
        // TODO Auto-generated method stub
        return null;
    }

}

现在我的的ContentProvider 是这样的:

public class ApplicationProvider  extends ContentProvider{
    //Define TAG FOR EACH CLASS FOR DEBUGGING 
    private static final String TAG = "ApplicationProvider";
    // Application CRUD Handlers use to support multiple tables inside the content provider
    private static Table1CRUD table1CRUD;
    private static Table2CRUD table2CRUD;

    static {
        table1CRUD = new Table1CRUD();
        table2CRUD= new Table2CRUD();

    }
    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        int uriMatchResult = ApplicationCRUD.sUriMatcher.match(uri);
        //case Table1
        if(uriMatchResult == Table1CRUD.INCOMING_COLLECTION_URI_INIDICATOR ||uriMatchResult == Table1CRUD.INCOMING_SINGLE_URI_INDICATOR )
        {
            return table1CRUD.delete(uri, selection, selectionArgs);
        }
        case Table2
        else if(uriMatchResult == Table2.INCOMING_COLLECTION_URI_INDICATOR|| uriMatchResult ==Table2.INCOMING_SINGLE_URI_INDICATOR){
            return table2CRUD.delete(uri, selection, selectionArgs);
        }

        else{
            throw new IllegalArgumentException("Unknown Uri "+uri);
        }
    }

现在我使用的是 SQLiteOpenHelper 作为私有类的的ContentProvider 而我在的ContentProvider 定义它的一个实例。我应该修改接口,并提供该对象依赖注入来让每个功能使用它来访问数据库的每个CRUD方法?我也想知道你怎么想这个方法:是不是不够好?这会让事情,我试图做有效的?我可以做的修改,以改善这种设计?

Now I am using the SQLiteOpenHelper as a private class in the ContentProvider and I define an instance of it in my ContentProvider. Should I modify the interface and supply each CRUD method that object Dependency Injection to let each function use it to access the database? I also want to know what you think about this approach: Is it good enough? Does it make the thing I am trying to do efficiently? What modification can I do to improve this design?

推荐答案

的谷歌IO调度的应用程序是一个很好的资源,如果你需要设计一个的ContentProvider 有多个表。这听起来像你想要做的事情有点复杂,但也许会有所帮助。

The Google IO Schedule application is a good resource if you are need to design a ContentProvider with multiple tables. It sounds like you want to do something a bit more complicated, but maybe it will help.