问题
I know this has been asked a couple of times before, but in all those questions neither the OP's nor the people who answered, provided clear examples.
So what I'm trying to ask here is if having a class like this
public class MyDatabaseDB {
// database constants
public static final String DB_NAME = "mydatabase.db";
public static final int DB_VERSION = 1;
// list table constants
public static final String LIST_TABLE = "list";
public static final String LIST_ID = "_id";
public static final int LIST_ID_COL = 0;
public static final String LIST_NAME = "list_name";
public static final int LIST_NAME_COL = 1;
// task table constants
public static final String TASK_TABLE = "task";
public static final String TASK_ID = "_id";
public static final int TASK_ID_COL = 0;
public static final String TASK_LIST_ID = "list_id";
public static final int TASK_LIST_ID_COL = 1;
public static final String TASK_NAME = "task_name";
public static final int TASK_NAME_COL = 2;
// CREATE and DROP TABLE statements
public static final String CREATE_LIST_TABLE =
"CREATE TABLE " + LIST_TABLE + " (" +
LIST_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
LIST_NAME + " TEXT UNIQUE)";
public static final String CREATE_TASK_TABLE =
"CREATE TABLE " + TASK_TABLE + " (" +
TASK_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
TASK_LIST_ID + " INTEGER, " +
TASK_NAME + " TEXT " +
)";
public static final String DROP_LIST_TABLE =
"DROP TABLE IF EXISTS " + LIST_TABLE;
public static final String DROP_TASK_TABLE =
"DROP TABLE IF EXISTS " + TASK_TABLE;
private static class DBHelper extends SQLiteOpenHelper {
public DBHelper(Context context, String name,
CursorFactory factory, int version) {
super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
// create tables
db.execSQL(CREATE_LIST_TABLE);
db.execSQL(CREATE_TASK_TABLE);
// insert lists
db.execSQL("INSERT INTO list VALUES (1, 'Hobbies')");
db.execSQL("INSERT INTO list VALUES (2, 'Sports')");
// insert sample tasks
db.execSQL("INSERT INTO task VALUES (1, 1, 'Play the guitar')");
db.execSQL("INSERT INTO task VALUES (2, 1, 'Play video games')");
}
@Override
public void onUpgrade(SQLiteDatabase db,
int oldVersion, int newVersion) {
Log.d("Task list", "Upgrading db from version "
+ oldVersion + " to " + newVersion);
db.execSQL(MyDatabaseDB.DROP_LIST_TABLE);
db.execSQL(MyDatabaseDB.DROP_TASK_TABLE);
onCreate(db);
}
}
// database object and database helper object
private SQLiteDatabase db;
private DBHelper dbHelper;
// constructor
public MyDatabaseDB(Context context) {
dbHelper = new DBHelper(context, DB_NAME, null, DB_VERSION);
}
// private methods
private void openReadableDB() {
db = dbHelper.getReadableDatabase();
}
private void openWriteableDB() {
db = dbHelper.getWritableDatabase();
}
private void closeDB() {
if (db != null)
db.close();
}
// public methods
public long insertTask(Task task) {
ContentValues cv = new ContentValues();
cv.put(TASK_LIST_ID, task.getListId());
cv.put(TASK_NAME, task.getName());
this.openWriteableDB();
long rowID = db.insert(TASK_TABLE, null, cv);
this.closeDB();
return rowID;
}
public int updateTask(Task task) {
ContentValues cv = new ContentValues();
cv.put(TASK_LIST_ID, task.getListId());
cv.put(TASK_NAME, task.getName());
String where = TASK_ID + "= ?";
String[] whereArgs = { String.valueOf(task.getId()) };
this.openWriteableDB();
int rowCount = db.update(TASK_TABLE, cv, where, whereArgs);
this.closeDB();
return rowCount;
}
public int deleteTask(long id) {
String where = TASK_ID + "= ?";
String[] whereArgs = { String.valueOf(id) };
this.openWriteableDB();
int rowCount = db.delete(TASK_TABLE, where, whereArgs);
this.closeDB();
return rowCount;
}
}
This is a very reduced version of my class , built using some code I found on-line. In this example I'm only showing the code for two of my tables : List and Task, and just some of the sql methods for the Task table : insertTask,updateTask, and deleteTask.
Even though the code shown above works, I don't think it would be nice to have all the code for let's say ten tables all in the same class. So I tried to split all these code into several classes , one for each table. Something like this:
public class MyDatabaseDB {
// database constants
public static final String DB_NAME = "mydatabase.db";
public static final int DB_VERSION = 1;
private static class DBHelper extends SQLiteOpenHelper {
public DBHelper(Context context, String name,
CursorFactory factory, int version) {
super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
// create tables
db.execSQL(ListDAL.CREATE_LIST_TABLE);
db.execSQL(TaskDAL.CREATE_TASK_TABLE);
// insert lists
db.execSQL("INSERT INTO list VALUES (1, 'Hobbies')");
db.execSQL("INSERT INTO list VALUES (2, 'Sports')");
// insert sample tasks
db.execSQL("INSERT INTO task VALUES (1, 1, 'Play the guitar')");
db.execSQL("INSERT INTO task VALUES (2, 1, 'Play video games')");
}
@Override
public void onUpgrade(SQLiteDatabase db,
int oldVersion, int newVersion) {
Log.d("Task list", "Upgrading db from version "
+ oldVersion + " to " + newVersion);
db.execSQL(ListDAL.DROP_LIST_TABLE);
db.execSQL(TaskDAL.DROP_TASK_TABLE);
onCreate(db);
}
}
// database object and database helper object
private SQLiteDatabase db;
private DBHelper dbHelper;
// constructor
public MyDatabaseDB(Context context) {
dbHelper = new DBHelper(context, DB_NAME, null, DB_VERSION);
}
// private methods
private void openReadableDB() {
db = dbHelper.getReadableDatabase();
}
private void openWriteableDB() {
db = dbHelper.getWritableDatabase();
}
private void closeDB() {
if (db != null)
db.close();
}
}
These are the two new classes, the I created to put the code related to a specific table :
The ListDAL doesn't have much code
public class ListDAL {
// list table constants
public static final String LIST_TABLE = "list";
public static final String LIST_ID = "_id";
public static final int LIST_ID_COL = 0;
public static final String LIST_NAME = "list_name";
public static final int LIST_NAME_COL = 1;
// CREATE and DROP TABLE statements
public static final String CREATE_LIST_TABLE =
"CREATE TABLE " + LIST_TABLE + " (" +
LIST_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
LIST_NAME + " TEXT UNIQUE)";
public static final String DROP_LIST_TABLE =
"DROP TABLE IF EXISTS " + LIST_TABLE;
}
The TaskDAL class is the one that contains most of the code, and it is in this class that I have problems, specifically in the insertTask,updateTask and deleteTask with calls like this.openWriteableDB(),this.openWriteableDB() or calls like db.insert(TASK_TABLE, null, cv).
Since these methods are no longer inside TaskDAL, I can't get access to them. I tried passing some references to these methods to be used in place of this or db, but it didn't work
public class TaskDAL {
// task table constants
public static final String TASK_TABLE = "task";
public static final String TASK_ID = "_id";
public static final int TASK_ID_COL = 0;
public static final String TASK_LIST_ID = "list_id";
public static final int TASK_LIST_ID_COL = 1;
public static final String TASK_NAME = "task_name";
public static final int TASK_NAME_COL = 2;
// CREATE and DROP TABLE statements
public static final String CREATE_TASK_TABLE =
"CREATE TABLE " + TASK_TABLE + " (" +
TASK_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
TASK_LIST_ID + " INTEGER, " +
TASK_NAME + " TEXT " +
)";
public static final String DROP_TASK_TABLE =
"DROP TABLE IF EXISTS " + TASK_TABLE;
// public methods
public long insertTask(Task task) {
ContentValues cv = new ContentValues();
cv.put(TASK_LIST_ID, task.getListId());
cv.put(TASK_NAME, task.getName());
this.openWriteableDB();
long rowID = db.insert(TASK_TABLE, null, cv);
this.closeDB();
return rowID;
}
public int updateTask(Task task) {
ContentValues cv = new ContentValues();
cv.put(TASK_LIST_ID, task.getListId());
cv.put(TASK_NAME, task.getName());
String where = TASK_ID + "= ?";
String[] whereArgs = { String.valueOf(task.getId()) };
this.openWriteableDB();
int rowCount = db.update(TASK_TABLE, cv, where, whereArgs);
this.closeDB();
return rowCount;
}
public int deleteTask(long id) {
String where = TASK_ID + "= ?";
String[] whereArgs = { String.valueOf(id) };
this.openWriteableDB();
int rowCount = db.delete(TASK_TABLE, where, whereArgs);
this.closeDB();
return rowCount;
}
}
So, have any of you ever tried to so something similar?? If I managed to correctly separate the DB code into several classes, would I be still able to JOIN tables??
P.S. Please do not close this question, if you think I did something wrong please tell me and I'll try to correct it
回答1:
do you think you could give some hints on how to do it
This has nothing much to do with Android, and even not all that much to do with Java. Decomposing long programming structures (e.g., classes in Java) into smaller structures has standard techniques, called design patterns, with language-specific implementations.
For example, you could go with the composite pattern:
Define an interface -- I'll call it
TableHelper
here -- that hasonCreate()
andonUpdate()
methods that match those onSQLiteOpenHelper
Define N classes, one per table, that implement the
TableHelper
interface and provide the create and upgrade logic for that table (along with whatever other business logic you want to have on those classes)Have your
SQLiteOpenHelper
define aTableHelper[]
containing instances of yourTableHelper
classes, and have it delegateonCreate()
andonUpgrade()
to thoseTableHelper
instances by iterating over the array
回答2:
Using a Content Provider, you can split your long SQLiteOpenHelper in a multiple files : one persistenceContract for each table, one little SQLiteOpenHelper, and long and verbose ContentProvider.
With this solution, you need to write more code. But it's more readable, and easy to maintain.
Avantages :
- Easy to name a column of a table when you write your query (example : TaskPersistenceContract.TaskEntry.COLUMN_TASK_NAME)
- Easy to read and maintain
- Less typo bugs
- Use cursor and CursorLoader logic
Disadvantage :
- More verbose
Let's try with your initial code !
1. Create a PersistenceContract for each table
ListPersistenceContract :
public final class ListPersistenceContract {
public static final String CONTENT_AUTHORITY = BuildConfig.APPLICATION_ID;
public static final String CONTENT_LIST_TYPE = "vnd.android.cursor.dir/" + CONTENT_AUTHORITY + "/" + ListEntry.TABLE_NAME;
public static final String CONTENT_LIST_ITEM_TYPE = "vnd.android.cursor.item/" + CONTENT_AUTHORITY + "/" + ListEntry.TABLE_NAME;
public static final String VND_ANDROID_CURSOR_ITEM_VND = "vnd.android.cursor.item/vnd." + CONTENT_AUTHORITY + ".";
private static final String CONTENT_SCHEME = "content://";
public static final Uri BASE_CONTENT_URI = Uri.parse(CONTENT_SCHEME + CONTENT_AUTHORITY);
private static final String VND_ANDROID_CURSOR_DIR_VND = "vnd.android.cursor.dir/vnd." + CONTENT_AUTHORITY + ".";
private static final String SEPARATOR = "/";
// To prevent someone from accidentally instantiating the contract class,
// give it an empty constructor.
private ListPersistenceContract() {}
public static Uri getBaseListUri(String listId) {
return Uri.parse(CONTENT_SCHEME + CONTENT_LIST_ITEM_TYPE + SEPARATOR + listId);
}
/* Inner class that defines the table contents */
public static abstract class ListEntry implements BaseColumns {
public static final String TABLE_NAME = "list";
public static final String COLUMN_LIST_NAME = "list_name";
public static final Uri CONTENT_LIST_URI = BASE_CONTENT_URI.buildUpon().appendPath(TABLE_NAME).build();
public static String[] LIST_COLUMNS = new String[]{
ListPersistenceContract.ListEntry._ID,
ListEntry.COLUMN_LIST_NAME};
public static final String LIST_AND_TASK = "listandtask";
public static Uri buildListUriWith(long id) {
return ContentUris.withAppendedId(CONTENT_LIST_URI, id);
}
public static Uri buildListUriWith(String id) {
Uri uri = CONTENT_LIST_URI.buildUpon().appendPath(id).build();
return uri;
}
public static Uri buildListUri() {
return CONTENT_LIST_URI.buildUpon().build();
}
public static Uri buildListAndTaskUri() {
return BASE_CONTENT_URI.buildUpon().appendPath(ListEntry.LIST_AND_TASK).build();
}
}
}
TaskPersistenceContract :
public class TaskPersistenceContract {
public static final String CONTENT_AUTHORITY = BuildConfig.APPLICATION_ID;
public static final String CONTENT_TASK_TYPE = "vnd.android.cursor.dir/" + CONTENT_AUTHORITY + "/" + TaskEntry.TABLE_NAME;
public static final String CONTENT_TASK_ITEM_TYPE = "vnd.android.cursor.item/" + CONTENT_AUTHORITY + "/" + TaskEntry.TABLE_NAME;
public static final String VND_ANDROID_CURSOR_ITEM_VND = "vnd.android.cursor.item/vnd." + CONTENT_AUTHORITY + ".";
private static final String CONTENT_SCHEME = "content://";
public static final Uri BASE_CONTENT_URI = Uri.parse(CONTENT_SCHEME + CONTENT_AUTHORITY);
private static final String VND_ANDROID_CURSOR_DIR_VND = "vnd.android.cursor.dir/vnd." + CONTENT_AUTHORITY + ".";
private static final String SEPARATOR = "/";
// To prevent someone from accidentally instantiating the contract class,
// give it an empty constructor.
private TaskPersistenceContract() {}
public static Uri getBaseTaskUri(String taskId) {
return Uri.parse(CONTENT_SCHEME + CONTENT_TASK_ITEM_TYPE + SEPARATOR + taskId);
}
/* Inner class that defines the table contents */
public static abstract class TaskEntry implements BaseColumns {
public static final String TABLE_NAME = "task";
public static final String COLUMN_TASK_LIST_ID = "list_id";
public static final String COLUMN_TASK_NAME = "task_name";
public static final Uri CONTENT_TASK_URI = BASE_CONTENT_URI.buildUpon().appendPath(TABLE_NAME).build();
public static String[] TASK_COLUMNS = new String[]{
TaskPersistenceContract.TaskEntry._ID,
TaskPersistenceContract.TaskEntry.COLUMN_TASK_LIST_ID,
TaskPersistenceContract.TaskEntry.COLUMN_TASK_NAME};
public static Uri buildTaskUriWith(long id) {
return ContentUris.withAppendedId(CONTENT_TASK_URI, id);
}
public static Uri buildTaskUriWith(String id) {
Uri uri = CONTENT_TASK_URI.buildUpon().appendPath(id).build();
return uri;
}
public static Uri buildTaskUri() {
return CONTENT_TASK_URI.buildUpon().build();
}
}
}
2. Create DbHelper
public class LocalDbHelper {
public static final int DB_VERSION = 1;
public static final String DB_NAME = "mydatabase.db";
private static final String TEXT_TYPE = " TEXT";
private static final String INTEGER_TYPE = " INTEGER";
private static final String PRIMARY_KEY = " PRIMARY KEY";
private static final String AUTOINCREMENT = " AUTOINCREMENT";
private static final String UNIQUE = " UNIQUE";
private static final String CREATE_TABLE = "CREATE TABLE ";
private static final String DROP_TABLE_IF_EXISTS = "DROP TABLE IF EXISTS ";
private static final String OPEN_PARENTHESIS = " (";
private static final String CLOSE_PARENTHESIS = " )";
private static final String COMMA_SEP = ",";
private static final String CREATE_LIST_TABLE =
CREATE_TABLE + ListPersistenceContract.ListEntry.TABLE_NAME + OPEN_PARENTHESIS +
ListPersistenceContract.ListEntry._ID + INTEGER_TYPE + PRIMARY_KEY + AUTOINCREMENT + COMMA_SEP +
ListPersistenceContract.ListEntry.COLUMN_LIST_NAME + TEXT_TYPE + UNIQUE +
CLOSE_PARENTHESIS;
private static final String CREATE_TASK_TABLE =
CREATE_TABLE + TaskPersistenceContract.TaskEntry.TABLE_NAME + OPEN_PARENTHESIS +
TaskPersistenceContract.TaskEntry._ID + INTEGER_TYPE + PRIMARY_KEY + AUTOINCREMENT + COMMA_SEP +
TaskPersistenceContract.TaskEntry.COLUMN_TASK_LIST_ID + INTEGER_TYPE + COMMA_SEP +
TaskPersistenceContract.TaskEntry.COLUMN_TASK_NAME + TEXT_TYPE +
CLOSE_PARENTHESIS;
private static final String DROP_LIST_TABLE =
DROP_TABLE_IF_EXISTS + ListPersistenceContract.ListEntry.TABLE_NAME;
private static final String DROP_TASK_TABLE =
DROP_TABLE_IF_EXISTS + TaskPersistenceContract.TaskEntry.TABLE_NAME;
public LocalDbHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
public void onCreate(SQLiteDatabase db) {
// create tables
db.execSQL(CREATE_LIST_TABLE);
db.execSQL(CREATE_TASK_TABLE);
// insert lists
db.execSQL("INSERT INTO " + ListPersistenceContract.ListEntry.TABLE_NAME + " VALUES (1, 'Hobbies')");
db.execSQL("INSERT INTO " + ListPersistenceContract.ListEntry.TABLE_NAME + " VALUES (2, 'Sports')");
// insert sample tasks
db.execSQL("INSERT INTO " + TaskPersistenceContract.TaskEntry.TABLE_NAME + " VALUES (1, 1, 'Play the guitar')");
db.execSQL("INSERT INTO " + TaskPersistenceContract.TaskEntry.TABLE_NAME + " VALUES (2, 1, 'Play video games')");
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.d("Task list", "Upgrading db from version "
+ oldVersion + " to " + newVersion);
db.execSQL(LocalDbHelper.DROP_LIST_TABLE);
db.execSQL(LocalDbHelper.DROP_TASK_TABLE);
onCreate(db);
}
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Not required as at version 1
}
}
3. Create ContentProvider with query, insert, update and delete operations
(in this example, i put a join of tables for a query. You can use the same logic for your insert, update and delete operations.)
public class MyAppContentProvider extends ContentProvider {
private static final int LIST = 100;
private static final int LIST_ITEM = 101;
private static final int LIST_AND_TASK = 102;
private static final int TASK = 200;
private static final int TASK_ITEM = 201;
private static final UriMatcher sUriMatcher = buildUriMatcher();
private LocalDbHelper mLocalDbHelper;
private static final SQLiteQueryBuilder sListAndTask;
static{
sListAndTask = new SQLiteQueryBuilder();
sListAndTask.setTables(
ListPersistenceContract.ListEntry.TABLE_NAME + " INNER JOIN " +
TaskPersistenceContract.TaskEntry.TABLE_NAME +
" ON " + ListPersistenceContract.ListEntry.TABLE_NAME +
"." + ListPersistenceContract.ListEntry._ID +
" = " + TaskPersistenceContract.TaskEntry.TABLE_NAME +
"." + TaskPersistenceContract.TaskEntry.COLUMN_TASK_LIST_ID);
}
private static UriMatcher buildUriMatcher() {
final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
final String authority = ListPersistenceContract.CONTENT_AUTHORITY;
matcher.addURI(authority, ListPersistenceContract.ListEntry.TABLE_NAME, LIST);
matcher.addURI(authority, ListPersistenceContract.ListEntry.TABLE_NAME + "/*", LIST_ITEM);
matcher.addURI(authority, ListPersistenceContract.ListEntry.LIST_AND_TASK, LIST_AND_TASK);
matcher.addURI(authority, TaskPersistenceContract.TaskEntry.TABLE_NAME, TASK);
matcher.addURI(authority, TaskPersistenceContract.TaskEntry.TABLE_NAME + "/*", TASK_ITEM);
return matcher;
}
@Override
public boolean onCreate() {
mLocalDbHelper = new LocalDbHelper(getContext());
return true;
}
@Nullable
@Override
public String getType(Uri uri) {
final int match = sUriMatcher.match(uri);
switch (match) {
case LIST:
return ListPersistenceContract.CONTENT_LIST_TYPE;
case LIST_ITEM:
return ListPersistenceContract.CONTENT_LIST_ITEM_TYPE;
case TASK:
return TaskPersistenceContract.CONTENT_TASK_TYPE;
case TASK_ITEM:
return TaskPersistenceContract.CONTENT_TASK_ITEM_TYPE;
default:
throw new UnsupportedOperationException("Unknown uri: " + uri);
}
}
@Nullable
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
Cursor retCursor;
switch (sUriMatcher.match(uri)) {
case LIST:
retCursor = mLocalDbHelper.getReadableDatabase().query(
ListPersistenceContract.ListEntry.TABLE_NAME,
projection,
selection,
selectionArgs,
null,
null,
sortOrder
);
break;
case LIST_ITEM:
String[] where_list = {uri.getLastPathSegment()};
retCursor = mLocalDbHelper.getReadableDatabase().query(
ListPersistenceContract.ListEntry.TABLE_NAME,
projection,
ListPersistenceContract.ListEntry._ID + " = ?",
where_list,
null,
null,
sortOrder
);
break;
case LIST_AND_TASK:
retCursor = sListAndTask.query(mLocalDbHelper.getReadableDatabase(),
projection,
selection,
selectionArgs,
null,
null,
sortOrder
);
break;
case TASK:
retCursor = mLocalDbHelper.getReadableDatabase().query(
TaskPersistenceContract.TaskEntry.TABLE_NAME,
projection,
selection,
selectionArgs,
null,
null,
sortOrder
);
break;
case TASK_ITEM:
String[] where_task = {uri.getLastPathSegment()};
retCursor = mLocalDbHelper.getReadableDatabase().query(
TaskPersistenceContract.TaskEntry.TABLE_NAME,
projection,
TaskPersistenceContract.TaskEntry._ID + " = ?",
where_task,
null,
null,
sortOrder
);
break;
default:
throw new UnsupportedOperationException("Unknown uri: " + uri);
}
retCursor.setNotificationUri(getContext().getContentResolver(), uri);
return retCursor;
}
@Nullable
@Override
public Uri insert(Uri uri, ContentValues values) {
final SQLiteDatabase db = mLocalDbHelper.getWritableDatabase();
final int match = sUriMatcher.match(uri);
Uri returnUri;
Cursor exists;
switch (match) {
case LIST:
exists = db.query(
ListPersistenceContract.ListEntry.TABLE_NAME,
new String[]{ListPersistenceContract.ListEntry._ID},
ListPersistenceContract.ListEntry._ID + " = ?",
new String[]{values.getAsString(ListPersistenceContract.ListEntry._ID)},
null,
null,
null
);
if (exists.moveToLast()) {
long _id = db.update(
ListPersistenceContract.ListEntry.TABLE_NAME, values,
ListPersistenceContract.ListEntry._ID + " = ?",
new String[]{values.getAsString(ListPersistenceContract.ListEntry._ID)}
);
if (_id > 0) {
returnUri = ListPersistenceContract.ListEntry.buildListUriWith(_id);
} else {
throw new android.database.SQLException("Failed to insert row into " + uri);
}
} else {
long _id = db.insert(ListPersistenceContract.ListEntry.TABLE_NAME, null, values);
if (_id > 0) {
returnUri = ListPersistenceContract.ListEntry.buildListUriWith(_id);
} else {
throw new android.database.SQLException("Failed to insert row into " + uri);
}
}
exists.close();
break;
case TASK:
exists = db.query(
TaskPersistenceContract.TaskEntry.TABLE_NAME,
new String[]{TaskPersistenceContract.TaskEntry._ID},
TaskPersistenceContract.TaskEntry._ID + " = ?",
new String[]{values.getAsString(TaskPersistenceContract.TaskEntry._ID)},
null,
null,
null
);
if (exists.moveToLast()) {
long _id = db.update(
TaskPersistenceContract.TaskEntry.TABLE_NAME, values,
TaskPersistenceContract.TaskEntry._ID + " = ?",
new String[]{values.getAsString(TaskPersistenceContract.TaskEntry._ID)}
);
if (_id > 0) {
returnUri = TaskPersistenceContract.TaskEntry.buildTaskUriWith(_id);
} else {
throw new android.database.SQLException("Failed to insert row into " + uri);
}
} else {
long _id = db.insert(TaskPersistenceContract.TaskEntry.TABLE_NAME, null, values);
if (_id > 0) {
returnUri = TaskPersistenceContract.TaskEntry.buildTaskUriWith(_id);
} else {
throw new android.database.SQLException("Failed to insert row into " + uri);
}
}
exists.close();
break;
default:
throw new UnsupportedOperationException("Unknown uri: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return returnUri;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
final SQLiteDatabase db = mLocalDbHelper.getWritableDatabase();
final int match = sUriMatcher.match(uri);
int rowsDeleted;
switch (match) {
case LIST:
rowsDeleted = db.delete(
ListPersistenceContract.ListEntry.TABLE_NAME, selection, selectionArgs);
break;
case TASK:
rowsDeleted = db.delete(
TaskPersistenceContract.TaskEntry.TABLE_NAME, selection, selectionArgs);
break;
default:
throw new UnsupportedOperationException("Unknown uri: " + uri);
}
if (selection == null || rowsDeleted != 0) {
getContext().getContentResolver().notifyChange(uri, null);
}
return rowsDeleted;
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
final SQLiteDatabase db = mLocalDbHelper.getWritableDatabase();
final int match = sUriMatcher.match(uri);
int rowsUpdated;
switch (match) {
case LIST:
rowsUpdated = db.update(ListPersistenceContract.ListEntry.TABLE_NAME, values, selection,
selectionArgs
);
break;
case TASK:
rowsUpdated = db.update(TaskPersistenceContract.TaskEntry.TABLE_NAME, values, selection,
selectionArgs
);
break;
default:
throw new UnsupportedOperationException("Unknown uri: " + uri);
}
if (rowsUpdated != 0) {
getContext().getContentResolver().notifyChange(uri, null);
}
return rowsUpdated;
}
}
来源:https://stackoverflow.com/questions/25549679/how-can-i-split-a-long-single-sqliteopenhelper-into-several-classes-one-for-ea