SQLiteOpenHelper, SQLiteDatabase, ContentProvider
SQLiteOpenHelperSQLiteDatabaseContentProvider三者的关系http://lzd20021683.iteye.com/blog/1277108
android之sqliteDatabase,sqliteOpenHelper,ContentProviderhttp://wang7839186.iteye.com/blog/1038880
SQLiteOpenHelper类
synchronizedvoidclose()
Closeanyopendatabaseobject.
synchronizedSQLiteDatabasegetReadableDatabase()
Createand/oropenadatabase.
synchronizedSQLiteDatabasegetWritableDatabase()
Createand/oropenadatabasethatwillbeusedforreadingandwriting.
abstractvoidonCreate(SQLiteDatabasedb)(在派生类中必须被重写)
Calledwhenthedatabaseiscreatedforthefirsttime.
voidonDowngrade(SQLiteDatabasedb,intoldVersion,intnewVersion)
Calledwhenthedatabaseneedstobedowngraded.
voidonOpen(SQLiteDatabasedb)
Calledwhenthedatabasehasbeenopened.
abstractvoidonUpgrade(SQLiteDatabasedb,intoldVersion,intnewVersion)(在派生类中必须被重写)
Calledwhenthedatabaseneedstobeupgraded.
它提供了两个重要的方法,分别是
onCreate(SQLiteDatabasedb):用户初次使用软件时生成数据库,一旦数据库存在则不会调用此方法。函数是在第一次创建数据库的时候执行的,仅仅生成DataBaseHelper对象(SQLiteOpenHelper类型)的时候是不会调用该函数的,而只有当调用DataBaseHelper对象的getReadableDataBase时或者是调用了getWritableDataBase时,如果是第一次创建数据库,那么就一定会调用onCreate()函数。
onUpgrade(SQLiteDatabasedb,intoldVersion,intvewVersion):用于升级软件时更新数据库表结构,如增加表、列字段等操作。
提示一下,在软件升级前,最好对原有数据进行备份,在新表建好后把数据导入新表中。
实现了这两个方法,就可以用它的getWritableDatabase()和getReadableDatabase()来获得数据库(SQLiteDatabase对象)。
强调下:当第一次创建数据库时,当实现DataBaseHelper对象的getReadableDataBase时或者是调用了getWritableDataBase时,系统自动调用oncreater()方法(当然程序中也可以调用);
如果用户需要升级数据库表结构,需要主动调用onUpgrade(SQLiteDatabasedb,intoldVersion,intvewVersion),传入一个新的版本的号。
继承该类并覆盖onCreate,onUpgrade,onOpen(可选)。我们可以创建或打开数据库,并对其进行升级。通过getReadableDataBase和getWritableDataBase获取SQliteDataBase实例。通过close关闭数据库。
SQLiteDatabase类:
SQLiteDatabase是关于数据库操作,封装了管理数据库的各种方法,包括insert、delete、update、query、执行SQL命令等操作。
其beginTransaction(),endTransaction()方法封装了开始及停止一个事务的相关SQL命令,yieldfContended()方法将暂停当前事务的运行已让其它等待线程执行。当该方法返回时,一个未标记为成功的新事务将被创建。
setMaximunSize(long)用于设置数据库文件的最大长度。
compileStatement(String)将一个SQL命令字符串转换为SQliteStatement对象,用于后续管理或执行。query()执行指定的SQL语句进行查询,并返回cursor作为结果。get/setVersion()获取霍设置数据库版本号。
insert(),update(),delete()执行数据库记录插入、更新、删除等工作。
execSQL()执行一条非查询类型的SQL命令,如:创建表,删除记录等。
setLocal()设置数据库的local。
可惜美中不足的是:
1.其不支持创建数据库
2.其不支持版本更新或者说其不知道如何做因为具体数据的差异
鉴于以上的缺陷,有一个辅助类可以完成上面功能,那就是:SQLiteOpenHelper
获得了SQLiteDatabase对象以后,我们就可以通过调用SQLiteDatabase的实例方法来对数据库进行操作了(通常,在ContentProvider派生类对象中,有一个SQLiteOpenHelper实例,通过SQLiteOpenHelper实例的getWritableDataBase或getReadableDataBase方法可以得到SQLiteDatabase对象实例)。
ContentProvider类
与Service,BroadcastReceiver等组件一样,继承特定的Interface,在AndroidManifest.xml里声明这个ContentProvider,调用者就可以拿来使用了。
首先我们定义一个ContentProvider:
package test.DB; import android.content.ContentProvider; import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; import android.widget.Toast; public class TestProvider extends ContentProvider { private DatabaseHelper mdbHelper = null; final static String TABLE_NAME = "test"; @Override public int delete(Uri arg0, String arg1, String[] arg2) { mdbHelper.getWritableDatabase().delete(TABLE_NAME, arg1, arg2); return 0; } @Override public String getType(Uri uri) { // TODO Auto-generated method stub return null; } @Override public Uri insert(Uri uri, ContentValues values) { // TODO Auto-generated method stub mdbHelper.getWritableDatabase().insert(TABLE_NAME, "", values); return null; } @Override public boolean onCreate() { // TODO Auto-generated method stub mdbHelper = new DatabaseHelper(this.getContext(), "dbfile"); return true; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { Cursor cur = mdbHelper.getReadableDatabase().query(TABLE_NAME,projection,selection,null,null,null, null); Toast.makeText(this.getContext(), "test Cur!", Toast.LENGTH_SHORT); return cur; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { mdbHelper.getWritableDatabase().update(TABLE_NAME, values, selection, null); return 0; } }
老规矩,AndroidManifest.xml来定义这个Provider
<provider android:label="test_provider" android:authorities="com.my.provider" android:name="TestProvider"> </provider>
这里的android:authorities="com.my.provider"是标识这个ContentProvider,调用者可以根据这个标识来找到它,
我们组合一个能找到它的Uri,
public class ProviderConst { public static final Uri MY_TEST_URI = Uri.parse("content://com.my.provider/test"); }
content指的是内容提供者ContentProvider。
//com.my.provider映射到我们已定义的那个ContentProvider标识
/test这个作为一个参数,传给ContentProvider,可以根据这个参数来决定操作目标,比如数据库中的哪张表,文件中的那一部分数据等。
我们来操作这个内容提供者:
private String getName() { String name = null; Cursor cur = this.getContentResolver().query(ProviderConst.MY_TEST_URI,new String[]{"id","name"},null, null, null); if (cur == null) return null; cur.moveToFirst(); do { name = name + cur.getString(1)+ "\n"; } while(cur.moveToNext()); return name; }
我们也可以这样使用:
private String getName() { String name = null; Cursor cur = this.managedQuery(ProviderConst.MY_TEST_URI,new String[]{"id","name"},null, null, null); if (cur == null) return null; cur.moveToFirst(); do { name = name + cur.getString(1)+ "\n"; } while(cur.moveToNext()); return name; }
简单的使用方法我们已了解