Я хочу реализовать ContentProvider
, который манипулирует несколькими таблицами. Вот что я попробовал до сих пор. Я написал Java Interface
, который представляет операции CRUD, которые каждая таблица должна реализовывать в своем классе 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);
}
Затем я написал abstract
class
, который определяет статический UriMatcher
для ContentProvider
, поэтому каждый класс, extends
этот класс должен добавить свой Uri
, который идентифицирует его и обеспечивает реализацию для каждого метода в интерфейсе.
Класс выглядит так:
public abstract class ApplicationCRUD implements CRUDHandler{
public static final UriMatcher sUriMatcher;
static {
sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
}
}
Далее, я создал класс для каждой таблицы, который extends
этот класс, и добавляет Uri
к UriMatcher
из абстрактного класса.
Вот пример:
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 этот объект Dependency Injection
, чтобы позволить каждой функции использовать его для доступа к базе данных? Я также хочу знать, что вы думаете об этом подходе: он достаточно хорош? Делает ли это то, что я пытаюсь сделать эффективно? Какие модификации я могу сделать, чтобы улучшить этот дизайн?