ContentProvider con varias tablas

Quiero implementar un ContentProvider que manipule varias tablas. Aquí es lo que he intentado hasta ahora. Escribí una Interface Java que representa las operaciones CRUD que cada tabla debería implementar en su clase CRUD.

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

Luego escribí una class abstract que define un UriMatcher estático para el ContentProvider por lo que cada clase que extends esta clase debe agregar su Uri que lo identifique y proporcionar una implementación para cada método en la interfaz.

La clase se ve así:

 public abstract class ApplicationCRUD implements CRUDHandler{ public static final UriMatcher sUriMatcher; static { sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); } } 

Además, creé una clase para cada tabla que extends esta clase y agrega sus Uri ‘s al UriMatcher desde la clase abstracta.

Aquí hay un ejemplo:

 public class Table1CRUD extends ApplicationCRUD { //Setup Projection Map for Table1 private static HashMapsTable1ProjectionMap; 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; } } 

Ahora mi ContentProvider ve así:

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

Ahora estoy usando el SQLiteOpenHelper como una clase privada en el ContentProvider y defino una instancia del mismo en mi ContentProvider . ¿Debo modificar la interfaz y proporcionar a cada método CRUD el objeto Dependency Injection para permitir que cada función lo use para acceder a la base de datos? También quiero saber qué piensa acerca de este enfoque: ¿Es lo suficientemente bueno? ¿Hace lo que estoy tratando de hacer de manera eficiente? ¿Qué modificación puedo hacer para mejorar este diseño?

La aplicación Google IO Schedule es un buen recurso si necesita diseñar un ContentProvider con varias tablas. Parece que quieres hacer algo un poco más complicado, pero tal vez te ayude.

He pasado por el proyecto de código abierto, en el que han utilizado varias tablas. Puede ver los diversos proyectos de OpenIntents y aquí hay una pregunta similar .
Espero que te pueda ayudar.

¿Por qué no haces múltiples tablas bajo un proveedor de contenido de esta manera?

Supongamos que tiene dos tablas llamadas A y B, su URI sería AUTHORITY / A, AUTHORITY / B

 private static final int TableOne = 1; private static final int TableTwo = 2; private static final UriMatcher uriMatcher; static{ uriMatcher.addUri(AUTHORITY,"A",TableOne); uriMatcher.addUri(AUTHORITY,"B",TableTwo); } 

Ahora puede implementar los métodos anulados utilizando un caso de conmutador estándar y asignando correctamente los métodos de la clase Base de datos SQLite subyacente.

Intereting Posts