當前位置:首頁 > IT技術(shù) > 移動平臺 > 正文

Android中的SQLite使用學習
2021-08-10 18:29:40

Android中的SQLite使用學習

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

?

SQLite支持絕大部分SQL-92標準,不支 持:FOREIGN KEY constraints, nested transactions, RIGHT OUTER JOIN, FULL OUTER JOIN, and some flavors of ALTER TABLE.而我們在手持終端上使用SQLite,一般并不涉及太復雜的數(shù)據(jù)庫處理,除了上訴,其他的SQL,包括tirger、transaction 等都是支持,應該說SQLite提供的功能是足夠。

?

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

?

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

?

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

?

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

?

/* 對于抽象類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){
?? ???? /* 第一個參數(shù) 為當前環(huán)境
???????? * 第二個參數(shù) String name為數(shù)據(jù)庫文件,如果數(shù)據(jù)存放在內(nèi)存 ,則為null,
?? ????? * 第三個參數(shù) 為SQLiteDatabase.CursorFactory? factory,存放cursor,缺省設(shè)置為null
?? ? ? ? * 第四個參數(shù) 為int version數(shù)據(jù)庫的版本,從1開始,如果版本舊,則通過onUpgrade()進行更新,如果版本新則通過onDowngrade()進行發(fā)布。例 如,我要更改mytable表格,增加一列,或者修改初始化的數(shù)據(jù),或者程序變得復雜,我需要增加一個表,這時我需要在版本的數(shù)字增加,在加載時,才會對 SQLite中的數(shù)據(jù)庫個更新,這點非常重要,同時參見onUpgrade()的說明 */

?? ??? ?super(context,DATABASE_BAME,null,1);
??? }
???
?? ?/*step 2 :重寫onCreate(),如果Android系統(tǒng)中第一次創(chuàng)建我們的數(shù)據(jù)庫時(即后面介紹調(diào)用getWritableDatabase()或者 getReadbleDatabase()時),將調(diào)用onCreate(),這這里創(chuàng)建數(shù)據(jù)庫(雖然在構(gòu)造函數(shù)中填入數(shù)據(jù)庫名,但數(shù)據(jù)庫的創(chuàng)建實在 onCreate()中自動進行。在這里一般進行創(chuàng)建table和寫入初始數(shù)據(jù)*/
?? ?public void onCreate(SQLiteDatabase db) {
?? ???? //創(chuàng)建table:SQL的語句是“CREATE TABLE constants(_id INTEGER PRIMARY KEY AUTOINCREMENT,title TEXT, value REAL);”,我們可以直接通過db.execSQL(SQLCommand)來執(zhí)行沒有返回值的SQL語言,例如CREATE,DELETE,UPDATE,INSERT,DROP。
?? ???? db.execSQL("CREATE TABLE mytable(_id INTEGER PRIMARY KEY AUTOINCREMENT, Name TEXT,Weight REAL); ");
?? ????
?? ???? //下面是加入三個原始數(shù)據(jù),如果對表格進行增、刪、改、查,后面會詳細介紹。下面的幾個數(shù)據(jù)來自Android自帶的重力表,據(jù)說是為了傳感器管理用,Android已經(jīng)考慮到我們在月球和火星上使用Android手機的情況^_^,程序員有時真的很無聊……
?? ??? ?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(),如果版本比原來的高,將調(diào)用onUpgrade(),在這個例子中,我們刪除原來的表格,根據(jù)新需求創(chuàng)建*/
?? ?public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
?? ???? //這次同樣通過db.execSQL(SQLCommand)來執(zhí)行沒有返回值的SQL語言,將表格刪除
?? ??? ?db.execSQL("DROP TABLE IF EXISTS mytable");
?? ??? ?onCreate(db);
?? ?}

}

?

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

?

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

?

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

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

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

?

3、對表格進行操作

?

對表格的操作有兩種方式,一種是RAW方式,即直接給出SQL語句,另一種是采用SQLiteDatabase中給出的方法來進行,姑且稱為API方式。下面就這兩種方式的增、刪、改、查進行實驗。

?

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

?

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

?

//RAW方式。
db.execSQL("INSERT INTO mytable(Name,Weight) VALUES ('Test1',1.0);");
//API方式,通過db.insert("mytable","Name",<ContentValues values>);來處理,其中ContentValues是用于存儲名稱和數(shù)值,對應為表格的列的名詞和其在行中的數(shù)據(jù)。
ContentValues values =new ContentValues(2);//ContentValues有兩個數(shù)值
values.put("Name", "Test2"); //一個列名為Name,數(shù)據(jù)為Test2
values.put("Weight", 2.0); //一個列名為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查詢和游標Cursor

?

上面的三個操作都是無返回值的,而查詢SELECT則不然,將返回游標Cursor。下面是兩種方式的查詢

?

//RAW方式,帶返回值,采用db.rawQuery(SQL語句)方式
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);

?

游標和Iterator接口有些相似,對于Cursor result我們可以通過下面的方式來讀取數(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();????

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

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

SQLite支持絕大部分SQL-92標準,不支 持:FOREIGN KEY constraints, nested transactions, RIGHT OUTER JOIN, FULL OUTER JOIN, and some flavors of ALTER TABLE.而我們在手持終端上使用SQLite,一般并不涉及太復雜的數(shù)據(jù)庫處理,除了上訴,其他的SQL,包括tirger、transaction 等都是支持,應該說SQLite提供的功能是足夠。

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

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

開通會員,享受整站包年服務立即開通 >