當(dāng)前位置:首頁(yè) > IT技術(shù) > 移動(dòng)平臺(tái) > 正文

Android中的SQLite使用學(xué)習(xí)
2021-08-10 18:29:40

Android中的SQLite使用學(xué)習(xí)

SQLite是非常流行的嵌入式關(guān)系型數(shù)據(jù)庫(kù),輕載, 速度快,而且是開源。在Android中,runtime提供SQLite,所以我們可以使用SQLite,而且是全集的SQLite。SQLite提供 SQL接口,和一般的數(shù)據(jù)庫(kù)一樣。但是Android的API不采用JDBC,JDBC消耗太多的資源。

?

SQLite支持絕大部分SQL-92標(biāo)準(zhǔn),不支 持:FOREIGN KEY constraints, nested transactions, RIGHT OUTER JOIN, FULL OUTER JOIN, and some flavors of ALTER TABLE.而我們?cè)谑殖纸K端上使用SQLite,一般并不涉及太復(fù)雜的數(shù)據(jù)庫(kù)處理,除了上訴,其他的SQL,包括tirger、transaction 等都是支持,應(yīng)該說(shuō)SQLite提供的功能是足夠。

?

和一般的SQL數(shù)據(jù)庫(kù)比較,最大的差異是數(shù)據(jù)類 型,例如我們定義一個(gè)表的某個(gè)column的數(shù)據(jù)類型為INTEGET,如果在插入時(shí)這個(gè)數(shù)值采用String,在SQLite中是包會(huì)產(chǎn)生錯(cuò)誤,我們可 以將定義表格的數(shù)據(jù)類型作為一個(gè)提示,用于說(shuō)明期待的數(shù)據(jù)類型,但是并不真實(shí)起到檢測(cè)作用。如果真的需要限制,要以來(lái)程序的其他部分進(jìn)行判斷。

?

1、建立我們的數(shù)據(jù)庫(kù)

?

在MySQL等數(shù)據(jù)庫(kù)中,第一步是創(chuàng)建數(shù)據(jù)庫(kù),第 二步是創(chuàng)建表,如需要,還加上我們的初始預(yù)制的數(shù)據(jù)。在Android的SQLite的使用是一樣的。稍微特別一點(diǎn)是,我們需要通過(guò)繼承 SQLiteOpenHelper這個(gè)類來(lái)達(dá)到目的。對(duì)于抽象類SQLiteOpenHelper的繼承,需要重 寫:1)constructor,2)onCreate()和onUpgrade(),下面舉例介紹。

?

這個(gè)例子,我們創(chuàng)建一個(gè)稱為bebook_db的數(shù)據(jù)庫(kù),里面有一個(gè)叫mytable的表格,有三列:_id,Name,Weight。下面我們將演示如何創(chuàng)建數(shù)據(jù)庫(kù),如何在數(shù)據(jù)庫(kù)中創(chuàng)建表,如何刪除表,如何更新數(shù)據(jù)庫(kù)。

?

/* 對(duì)于抽象類SQLiteOpenHelper的繼承,需要重寫:1)constructor,2)onCreate()和onUpgrade()? * */
public class Chapter22Db extends SQLiteOpenHelper{
?? ?public static final String DATABASE_BAME ="bebook_db";

?? ?/* step 1 :重寫構(gòu)造函數(shù)中,繼承super的構(gòu)造函數(shù),創(chuàng)建database */
??? public Chapter22Db(Context context){
?? ???? /* 第一個(gè)參數(shù) 為當(dāng)前環(huán)境
???????? * 第二個(gè)參數(shù) String name為數(shù)據(jù)庫(kù)文件,如果數(shù)據(jù)存放在內(nèi)存 ,則為null,
?? ????? * 第三個(gè)參數(shù) 為SQLiteDatabase.CursorFactory? factory,存放cursor,缺省設(shè)置為null
?? ? ? ? * 第四個(gè)參數(shù) 為int version數(shù)據(jù)庫(kù)的版本,從1開始,如果版本舊,則通過(guò)onUpgrade()進(jìn)行更新,如果版本新則通過(guò)onDowngrade()進(jìn)行發(fā)布。例 如,我要更改mytable表格,增加一列,或者修改初始化的數(shù)據(jù),或者程序變得復(fù)雜,我需要增加一個(gè)表,這時(shí)我需要在版本的數(shù)字增加,在加載時(shí),才會(huì)對(duì) SQLite中的數(shù)據(jù)庫(kù)個(gè)更新,這點(diǎn)非常重要,同時(shí)參見onUpgrade()的說(shuō)明 */

?? ??? ?super(context,DATABASE_BAME,null,1);
??? }
???
?? ?/*step 2 :重寫onCreate(),如果Android系統(tǒng)中第一次創(chuàng)建我們的數(shù)據(jù)庫(kù)時(shí)(即后面介紹調(diào)用getWritableDatabase()或者 getReadbleDatabase()時(shí)),將調(diào)用onCreate(),這這里創(chuàng)建數(shù)據(jù)庫(kù)(雖然在構(gòu)造函數(shù)中填入數(shù)據(jù)庫(kù)名,但數(shù)據(jù)庫(kù)的創(chuàng)建實(shí)在 onCreate()中自動(dòng)進(jìn)行。在這里一般進(jìn)行創(chuàng)建table和寫入初始數(shù)據(jù)*/
?? ?public void onCreate(SQLiteDatabase db) {
?? ???? //創(chuàng)建table:SQL的語(yǔ)句是“CREATE TABLE constants(_id INTEGER PRIMARY KEY AUTOINCREMENT,title TEXT, value REAL);”,我們可以直接通過(guò)db.execSQL(SQLCommand)來(lái)執(zhí)行沒有返回值的SQL語(yǔ)言,例如CREATE,DELETE,UPDATE,INSERT,DROP。
?? ???? db.execSQL("CREATE TABLE mytable(_id INTEGER PRIMARY KEY AUTOINCREMENT, Name TEXT,Weight REAL); ");
?? ????
?? ???? //下面是加入三個(gè)原始數(shù)據(jù),如果對(duì)表格進(jìn)行增、刪、改、查,后面會(huì)詳細(xì)介紹。下面的幾個(gè)數(shù)據(jù)來(lái)自Android自帶的重力表,據(jù)說(shuō)是為了傳感器管理用,Android已經(jīng)考慮到我們?cè)谠虑蚝突鹦巧鲜褂肁ndroid手機(jī)的情況^_^,程序員有時(shí)真的很無(wú)聊……
?? ??? ?ContentValues cv = new ContentValues();
?? ??? ?
?? ??? ?cv.put("Name", "Gravity, Earth");
?? ??? ?cv.put("Weight", SensorManager.GRAVITY_EARTH);
?? ??? ?db.insert("mytable", "Name", cv);
?? ??? ?
?? ??? ?cv.put("Name", "Gravity, Mars");
?? ??? ?cv.put("Weight", SensorManager.GRAVITY_MARS);
?? ??? ?db.insert("mytable", "Name", cv);

?? ??? ?cv.put("Name", "Gravity, Moon");
?? ??? ?cv.put("Weight", SensorManager.GRAVITY_MOON);
?? ??? ?db.insert("mytable", "Name", cv);
??? }

??? /* step 3:重寫onUpgrade(),如果版本比原來(lái)的高,將調(diào)用onUpgrade(),在這個(gè)例子中,我們刪除原來(lái)的表格,根據(jù)新需求創(chuàng)建*/
?? ?public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
?? ???? //這次同樣通過(guò)db.execSQL(SQLCommand)來(lái)執(zhí)行沒有返回值的SQL語(yǔ)言,將表格刪除
?? ??? ?db.execSQL("DROP TABLE IF EXISTS mytable");
?? ??? ?onCreate(db);
?? ?}

}

?

2、和數(shù)據(jù)庫(kù)進(jìn)行關(guān)聯(lián)

?

就如同在MYSQL中進(jìn)行來(lái)數(shù)據(jù)庫(kù)的創(chuàng)建,表格創(chuàng) 建和初始數(shù)據(jù)的填寫,其他的操作一般在Activity中和用戶互動(dòng)產(chǎn)生?;貞浺幌挛覀?cè)贚inux環(huán)境中如何處理,首先是要?jiǎng)?chuàng)建和數(shù)據(jù)庫(kù)的連 接,Android也一樣,另外在Activity結(jié)束時(shí),我們需要將連接斷開,以釋放有關(guān)資源。

?

public class Chapter22Test1 extends ListActivity{
?? ?private SQLiteDatabase? db = null;
?? ?private Cursor cursor = null; //在后面與ListView互動(dòng)中使用

??? protected void onCreate(Bundle savedInstanceState) {
?? ???? super.onCreate(savedInstanceState);
?? ???? // 獲取處理SQLiteOpenHelper的子類的SQLite的實(shí)例,如果只讀,可以采用getReadableDatabase(),這個(gè)例子我們獎(jiǎng)通過(guò)SQLiteDatabase實(shí)例的操作,來(lái)進(jìn)行對(duì)數(shù)據(jù)進(jìn)行增刪改查詢,采用可寫的方式。
?? ??? ?db= (new Chapter22Db (getApplicationContext())).getWritableDatabase();??
?? ?}

??? protected void onDestroy() {
?? ???? super.onDestroy();
?? ??? //釋放和數(shù)據(jù)庫(kù)的連接
?? ??? ?db.close();
?? ?}
}

?

3、對(duì)表格進(jìn)行操作

?

對(duì)表格的操作有兩種方式,一種是RAW方式,即直接給出SQL語(yǔ)句,另一種是采用SQLiteDatabase中給出的方法來(lái)進(jìn)行,姑且稱為API方式。下面就這兩種方式的增、刪、改、查進(jìn)行實(shí)驗(yàn)。

?

3.1增加一行數(shù)據(jù)

?

在設(shè)置創(chuàng)建表格時(shí),使用了db.execSQL(SQLCommand)來(lái)執(zhí)行沒有返回值的SQL語(yǔ)言,這個(gè)是RAW方式。另一種方式在之前加入原始數(shù)據(jù)時(shí)給出,通過(guò)db.insert("mytable","Name",<ContentValues values>);來(lái)實(shí)現(xiàn)。其中第二個(gè)參數(shù)比較特別。SQL是不運(yùn)行加入一個(gè)空的行。如果第二個(gè)參數(shù)不設(shè)置為null,則對(duì)這種情空行情況進(jìn)行處理,將對(duì)應(yīng)列的值設(shè)置為“NULL”。

?

//RAW方式。
db.execSQL("INSERT INTO mytable(Name,Weight) VALUES ('Test1',1.0);");
//API方式,通過(guò)db.insert("mytable","Name",<ContentValues values>);來(lái)處理,其中ContentValues是用于存儲(chǔ)名稱和數(shù)值,對(duì)應(yīng)為表格的列的名詞和其在行中的數(shù)據(jù)。
ContentValues values =new ContentValues(2);//ContentValues有兩個(gè)數(shù)值
values.put("Name", "Test2"); //一個(gè)列名為Name,數(shù)據(jù)為Test2
values.put("Weight", 2.0); //一個(gè)列名為Weight,數(shù)據(jù)為2.0
db.insert("mytable","Name",values);

?

3.2刪除一行數(shù)據(jù)

?

//RAW方式
db.execSQL("DELETE FROM mytable WHERE Name='Test1';");?? ?
//API方式,方法是:delete (String table, String whereClause, String[] whereArgs)
db.delete("mytable", "Name=?", {"Test1"});

?

3.3更新一行數(shù)據(jù)

?

//RAW方式
db.execSQL("UPDATE mytable SET Weight=5.0 WHERE Name='Test1';");
//API方式,方法是:update (String table, ContentValuesvalues, StringwhereClause, String[]whereArgs)
String[] name = {"Test1"};
ContentValues values =new ContentValues(2);

values.put("Name", "Test1");
values.put("Weight", 5.0);

db.update("mytable",values,"Name=?",name);

?

3.4查詢和游標(biāo)Cursor

?

上面的三個(gè)操作都是無(wú)返回值的,而查詢SELECT則不然,將返回游標(biāo)Cursor。下面是兩種方式的查詢

?

//RAW方式,帶返回值,采用db.rawQuery(SQL語(yǔ)句)方式
Cursor result1 =db.rawQuery("SELECT _id,Name,Weight from mytable ORDER BY Name", null);

/API 方式,帶返回值,采用public Cursor query (String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy)
String[] columns ={"Name","Weight"};
String[] name ={"Name"};

Cursor result2 = db.query("mytable", columns, "Name=?", name, null, null, null);

?

游標(biāo)和Iterator接口有些相似,對(duì)于Cursor result我們可以通過(guò)下面的方式來(lái)讀取數(shù)據(jù):

?

result.moveToFirst();
while(!result.isAfterLast()){
?? ?int id = result.getInt(0);
?? ?String name = result.getString(1);
?? ?double weight = result.getDouble(2);
?? ?System.out.println(" "+id + " ["+ name + "] " +weight);
?? ?result.moveToNext();
}?? ??? ?
result.close();????

通過(guò)Cursor我們可以讀取數(shù)據(jù)庫(kù)的詳細(xì)信息我 們可以數(shù)據(jù)用ArrayList<HashMap<>>來(lái)存放,由于real非對(duì)象,簡(jiǎn)單地用 ArrayList<HashMap<String,String>>來(lái)存儲(chǔ)。我們已經(jīng)有能力對(duì)SQLite數(shù)據(jù)進(jìn)行處理,并也 有能力處理ListView,這樣可以編寫我們的Activity。

SQLite是非常流行的嵌入式關(guān)系型數(shù)據(jù)庫(kù),輕載, 速度快,而且是開源。在Android中,runtime提供SQLite,所以我們可以使用SQLite,而且是全集的SQLite。SQLite提供 SQL接口,和一般的數(shù)據(jù)庫(kù)一樣。但是Android的API不采用JDBC,JDBC消耗太多的資源。

SQLite支持絕大部分SQL-92標(biāo)準(zhǔn),不支 持:FOREIGN KEY constraints, nested transactions, RIGHT OUTER JOIN, FULL OUTER JOIN, and some flavors of ALTER TABLE.而我們?cè)谑殖纸K端上使用SQLite,一般并不涉及太復(fù)雜的數(shù)據(jù)庫(kù)處理,除了上訴,其他的SQL,包括tirger、transaction 等都是支持,應(yīng)該說(shuō)SQLite提供的功能是足夠。

Face your past without regret. Handle your present with confidence.Prepare for future without fear. keep the faith and drop the fear. 面對(duì)過(guò)去無(wú)怨無(wú)悔,把握現(xiàn)在充滿信心,備戰(zhàn)未來(lái)無(wú)所畏懼。保持信念,克服恐懼!一點(diǎn)一滴的積累,一點(diǎn)一滴的沉淀,學(xué)技術(shù)需要不斷的積淀!

本文摘自 :https://blog.51cto.com/u

開通會(huì)員,享受整站包年服務(wù)立即開通 >