大家都知道Android数据库使用的是SQLite,但是Google为了给我们简化操作,可以不用经常编写容易出错的SQL语句,直接通过ContentProvider来封装数据的query查询、添加insert、删除delete和更新update,我们就以Android系统的SDK中的例子来给大家简单的说明下吧。

public class NotePadProvider extends ContentProvider {

private static final String TAG = "NotePadProvider";

private static final String DATABASE_NAME = "note_pad.db"; //数据库存储文件名,包含了.db后缀

private static final int DATABASE_VERSION = 2; //数据库版本号,这个是自己定义的,未来扩展数据库时自己可以方便的定义升级规则

private static final String NOTES_TABLE_NAME = "notes"; //表名

private static HashMap sNotesProjectionMap; //常规的Notes

private static HashMap sLiveFolderProjectionMap; //LiveFoder内容

private static final int NOTES = 1;

private static final int NOTE_ID = 2;

private static final int LIVE_FOLDER_NOTES = 3;

private static final UriMatcher sUriMatcher; //这里Android123提示大家,通常我们操作数据库的Uri比如content://android123/cwj/1103这样的Uri均通过UriMatcher注册并识别的。

private static class DatabaseHelper extends SQLiteOpenHelper { //数据库辅助子类

DatabaseHelper(Context context) {

super(context, DATABASE_NAME, null, DATABASE_VERSION);

}

@Override

public void onCreate(SQLiteDatabase db) { //首次生成数据库,执行sql命令创建一个表

db.execSQL("CREATE TABLE " + NOTES_TABLE_NAME + " ("

+ Notes._ID + " INTEGER PRIMARY KEY,"

+ Notes.TITLE + " TEXT,"

+ Notes.NOTE + " TEXT,"

+ Notes.CREATED_DATE + " INTEGER,"

+ Notes.MODIFIED_DATE + " INTEGER"

+ ");");

}

@Override

public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { //刚来数据的版本,就是为了定义我们如果未来数据库需要扩展,帮助用户识别并根据规则自动升级数据库文件

Log.w(TAG, "Upgrading database from version " + oldVersion + " to "

+ newVersion + ", which will destroy all old data");

db.execSQL("DROP TABLE IF EXISTS notes"); //由于这里没有做细节处理,如果有新版本,删除老的表,我们未来不能这样处理,这仅仅是Google的例子而已所以删除老版本数据

onCreate(db);

}

}

private DatabaseHelper mOpenHelper;

@Override

public boolean onCreate() { //这里重写ContentProvider的onCreate方法做一些初始化操作

mOpenHelper = new DatabaseHelper(getContext());

return true;

}

//有关数据库的查询操作,Android的SQLite提供了一个SQLiteQueryBuilder方法再次将SQL命令封装了下,单独分离出表名,排序方法等

@Override

public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,

String sortOrder) {

SQLiteQueryBuilder qb = new SQLiteQueryBuilder();

qb.setTables(NOTES_TABLE_NAME);

switch (sUriMatcher.match(uri)) {

case NOTES:

qb.setProjectionMap(sNotesProjectionMap);

break;

case NOTE_ID:

qb.setProjectionMap(sNotesProjectionMap);

qb.appendWhere(Notes._ID + "=" + uri.getPathSegments().get(1));

break;

case LIVE_FOLDER_NOTES:

qb.setProjectionMap(sLiveFolderProjectionMap);

break;

default:

throw new IllegalArgumentException("Unknown URI " + uri);

}

String orderBy;

if (TextUtils.isEmpty(sortOrder)) {

orderBy = NotePad.Notes.DEFAULT_SORT_ORDER;

} else {

orderBy = sortOrder;

}

SQLiteDatabase db = mOpenHelper.getReadableDatabase();

Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, orderBy);

c.setNotificationUri(getContext().getContentResolver(), uri);

return c;

}

@Override

public String getType(Uri uri) {

switch (sUriMatcher.match(uri)) {

case NOTES:

case LIVE_FOLDER_NOTES:

return Notes.CONTENT_TYPE;

case NOTE_ID:

return Notes.CONTENT_ITEM_TYPE;

default:

throw new IllegalArgumentException("Unknown URI " + uri);

}

}

有关数据的插入操作,重写ContentProvider的insert方法即可

@Override

public Uri insert(Uri uri, ContentValues initialValues) {

if (sUriMatcher.match(uri) != NOTES) {

throw new IllegalArgumentException("Unknown URI " + uri);

}

ContentValues values;

if (initialValues != null) {

values = new ContentValues(initialValues);

} else {

values = new ContentValues();

}

Long now = Long.valueOf(System.currentTimeMillis());

if (values.containsKey(NotePad.Notes.CREATED_DATE) == false) {

values.put(NotePad.Notes.CREATED_DATE, now);

}

if (values.containsKey(NotePad.Notes.MODIFIED_DATE) == false) {

values.put(NotePad.Notes.MODIFIED_DATE, now);

}

if (values.containsKey(NotePad.Notes.TITLE) == false) {

Resources r = Resources.getSystem();

values.put(NotePad.Notes.TITLE, r.getString(android.R.string.untitled));

}

if (values.containsKey(NotePad.Notes.NOTE) == false) {

values.put(NotePad.Notes.NOTE, "");

}

SQLiteDatabase db = mOpenHelper.getWritableDatabase();

long rowId = db.insert(NOTES_TABLE_NAME, Notes.NOTE, values);

if (rowId > 0) {

Uri noteUri = ContentUris.withAppendedId(NotePad.Notes.CONTENT_URI, rowId);

getContext().getContentResolver().notifyChange(noteUri, null); //通知数据库内容有改变

return noteUri;

}

throw new SQLException("Failed to insert row into " + uri);

}

@Override

public int delete(Uri uri, String where, String[] whereArgs) {

SQLiteDatabase db = mOpenHelper.getWritableDatabase();

int count;

switch (sUriMatcher.match(uri)) {

case NOTES:

count = db.delete(NOTES_TABLE_NAME, where, whereArgs);

break;

case NOTE_ID:

String noteId = uri.getPathSegments().get(1);

count = db.delete(NOTES_TABLE_NAME, Notes._ID + "=" + noteId

+ (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);

break;

default:

throw new IllegalArgumentException("Unknown URI " + uri);

}

getContext().getContentResolver().notifyChange(uri, null);

return count;

}

@Override

public int update(Uri uri, ContentValues values, String where, String[] whereArgs) {

SQLiteDatabase db = mOpenHelper.getWritableDatabase();

int count;

switch (sUriMatcher.match(uri)) {

case NOTES:

count = db.update(NOTES_TABLE_NAME, values, where, whereArgs);

break;

case NOTE_ID:

String noteId = uri.getPathSegments().get(1);

count = db.update(NOTES_TABLE_NAME, values, Notes._ID + "=" + noteId

+ (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);

break;

default:

throw new IllegalArgumentException("Unknown URI " + uri);

}

getContext().getContentResolver().notifyChange(uri, null);

return count;

}

最后我们需要在构造奔雷时就监听Uri,如果处理的Uri需要其他程序获知,需要在Androidmanifest.xml文件中显式的导出provider的Uri定义

static {

sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);

sUriMatcher.addURI(NotePad.AUTHORITY, "notes", NOTES);

sUriMatcher.addURI(NotePad.AUTHORITY, "notes/#", NOTE_ID);

sUriMatcher.addURI(NotePad.AUTHORITY, "live_folders/notes", LIVE_FOLDER_NOTES);

sNotesProjectionMap = new HashMap();

sNotesProjectionMap.put(Notes._ID, Notes._ID);

sNotesProjectionMap.put(Notes.TITLE, Notes.TITLE);

sNotesProjectionMap.put(Notes.NOTE, Notes.NOTE);

sNotesProjectionMap.put(Notes.CREATED_DATE, Notes.CREATED_DATE);

sNotesProjectionMap.put(Notes.MODIFIED_DATE, Notes.MODIFIED_DATE);

// Support for Live Folders.

sLiveFolderProjectionMap = new HashMap();

sLiveFolderProjectionMap.put(LiveFolders._ID, Notes._ID + " AS " +

LiveFolders._ID);

sLiveFolderProjectionMap.put(LiveFolders.NAME, Notes.TITLE + " AS " +

LiveFolders.NAME);

// Add more columns here for more robust Live Folders.

}

}

最后安博中程网站帮助初学者简单的概括下Android的ContentProvider类的作用,就是尽可能的减少SQL语句的编写在外部操作,封装成方法,而有关SQL语言的执行在DatabaseHelper中也被简化和分离出了,而SQL语句主要是体现在选择表的字段,where这样的条件限定语句大大减少了我们日常的开发。

更多相关文章

  1. SpringBoot 2.0 中 HikariCP 数据库连接池原理解析
  2. adb命令基本操作
  3. Android(安卓)Studio一个连接SQLite数据库的登录注册实现
  4. android 中SQLite数据库多条插入如何提高效率
  5. Android(安卓)Contextual ActionBar (CAB)上下文操作栏使用指南
  6. Android(安卓)studio 数据库可视化操作
  7. android 中 SQLiteOpenHelper的封装使用详解
  8. Android里监视数据库的变化[转]
  9. android 数据存储之SQLite

随机推荐

  1. android makefile(android.mk)分析(转)
  2. Android(安卓)Camera 流程学习记录(一)——
  3. Android 7.1预编译编译第三方so
  4. 修改eclipse android 默认debug 签名
  5. 《Android开发从零开始》——9.Activity
  6. Android NullPointerException解决方法
  7. 10个android开源项目
  8. 十大Android IDE工具和应用
  9. Android开发平台Android Studio学习之一(
  10. 【原创】Android锁定横竖屏、splash,全屏