这一节详细介绍一下Model层的设计,本身并无太多难点,采用标准的Provider结构访问底层数据库。简单UML图如下:
通过ThemeProvider统一访问数据库具体实现ThemeDBHelper。通过向ThemeProvider添加相应的Observer来监听数据库的变化。这里属于标准的Provider操作、及sqlite操作,由于不涉及到多个应用数据共享的操作,只是使用Provider接管、简化对数据库的访问操作,所以实现相对简单,唯一需要注意的是由于需要Observer来监听数据库的变化,所以在Provider的相关操作后,需要通过sendNotification来通知相关监听器。
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;
public class ThemeProvider extends ContentProvider {
private final static String TAG = ThemeProvider.class.toString();
public static final String AUTHORITY = "com.tencent.themedatabase";// 对外提供服务接口名
public static final String NOTIFICATION = "notify";// 是否通知提示
private static ThemeDBHelper mThemeDBHelper;
private Context mContext;
// public ThemeProvider(Context context) {
// mContext = context;
// mThemeDBHelper = new ThemeDBHelper(context);
//
// }
private long checkandInsert(SQLiteDatabase db, ContentValues cv,
String table, String nullColumnHack) {
if (cv.get(ThemeDBHelper._ID) == null) {
throw new RuntimeException("Error : the Insert value has no id");
}
return db.insert(table, nullColumnHack, cv);
}
private void sendNotify(Uri uri) {
String notify = uri.getQueryParameter(NOTIFICATION);
if (notify == null || notify.equals("true")) {
mContext.getContentResolver().notifyChange(uri, null);
}
}
public static long generateNewId() {
return mThemeDBHelper.generateNewId();
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
/**/
SqlArguments sqlargs = new SqlArguments(uri, selection, selectionArgs);
SQLiteDatabase db = mThemeDBHelper.getWritableDatabase();
int count = db.delete(sqlargs.table, sqlargs.where, sqlargs.selection);
if (count > 0) {
sendNotify(uri);
}
return 0;
}
@Override
public String getType(Uri uri) {
SqlArguments sqlarg = new SqlArguments(uri);
if (TextUtils.isEmpty(sqlarg.where)) {
return "vnd.android.cursor.dir/" + sqlarg.table;
} else {
return "vnd.android.cursor.item/" + sqlarg.table;
}
}
@Override
public Uri insert(Uri uri, ContentValues values) {
SqlArguments sqlargs = new SqlArguments(uri);
SQLiteDatabase db = mThemeDBHelper.getWritableDatabase();
long id = checkandInsert(db, values, sqlargs.table, null);
if (id < 0) {
return null;
}
uri = ContentUris.withAppendedId(uri, id);
sendNotify(uri);
return uri;
}
@Override
public int bulkInsert(Uri uri, ContentValues[] values) {
SqlArguments sqlargs = new SqlArguments(uri);
SQLiteDatabase db = mThemeDBHelper.getWritableDatabase();
db.beginTransaction();
try {
for(int i=0; i<values.length;i++){
if(checkandInsert(db, values[i],sqlargs.table, null) <0){
return 0;
}
}
db.setTransactionSuccessful();
} catch (Exception e) {
e.printStackTrace();
}
finally{
db.endTransaction();
}
sendNotify(uri);
return values.length;
}
@Override
public boolean onCreate() {
mContext = this.getContext();
mThemeDBHelper = new ThemeDBHelper(mContext);
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SqlArguments sqlargs = new SqlArguments(uri, selection, selectionArgs);
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
qb.setTables(sqlargs.table);
SQLiteDatabase db = mThemeDBHelper.getReadableDatabase();
Cursor cr = qb.query(db, projection, sqlargs.where, sqlargs.selection,
null, null, sortOrder);
cr.setNotificationUri(mContext.getContentResolver(), uri);
return cr;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
SqlArguments sqlargs = new SqlArguments(uri, selection, selectionArgs);
SQLiteDatabase db = mThemeDBHelper.getWritableDatabase();
int count = db.update(sqlargs.table, values, sqlargs.where,
sqlargs.selection);
Log.e(TAG,"GET WHERE "+sqlargs.where);
if (count > 0) {
sendNotify(uri);
}
return count;
}
static class SqlArguments {
/**
* 处理sql语句,解析各个参数
* */
public final String table;
public final String where;
public final String[] selection;
public SqlArguments(Uri uri, String where, String[] selection) {
int argscount = uri.getPathSegments().size();
if (argscount == 1) {
// uri://host/table
this.table = uri.getPathSegments().get(0);
Log.e("pluszhang","parse uri "+this.table);
this.where = where;
this.selection = selection;
} else if (argscount != 2) {
// uri://host/table/id/...
throw new IllegalArgumentException("Invalidate URI " + uri);
} else if (!TextUtils.isEmpty(where)) {
// uri://host/talbe/id,where应该为空,已经指明id
throw new UnsupportedOperationException(
"WHERE opt not support " + uri);
} else {
// uri://host/table/id
this.table = uri.getPathSegments().get(0);
this.where = "_id=" + uri.getPathSegments().get(1);
this.selection = null;
}
}
public SqlArguments(Uri uri) {
if (uri.getPathSegments().size() == 1) {
this.table = uri.getPathSegments().get(0);
this.where = null;
this.selection = null;
} else {
throw new IllegalArgumentException("Invalidate URI " + uri);
}
}
}
}
——欢迎转载,请注明出处http://blog.csdn.net/zyplus——