SQLite的使用

SQLite是非常流行的嵌入式關係型數據庫,輕載,速度快,而且是開源。在Android中,runtime提供SQLite,所以我們可以使用SQLite,而且是全集的SQLite。SQLite提供SQL接口,和一般的數據庫一樣。但是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,一般並不涉及太複雜的數據庫處理,除了上訴,其他的SQL,包括tirger、transaction等都是支持,應該說SQLite提供的功能是足夠。

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

1、建立我們的數據庫

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

這個例子,我們創建一個稱爲bebook_db的數據庫,裏面有一個叫mytable的表格,有三列:_id,Name,Weight。下面我們將演示如何創建數據庫,如何在數據庫中創建表,如何刪除表,如何更新數據庫。

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

    /* step 1 :重寫構造函數中,繼承super的構造函數,創建database */
    public Chapter22Db(Context context){
        /* 第一個參數 爲當前環境
         * 第二個參數 String name爲數據庫文件,如果數據存放在內存 ,則爲null,
         * 第三個參數 爲SQLiteDatabase.CursorFactory  factory,存放cursor,缺省設置爲null
         * 第四個參數 爲int version數據庫的版本,從1開始,如果版本舊,則通過onUpgrade()進行更新,如果版本新則通過onDowngrade()進行發佈。例如,我要更改mytable表格,增加一列,或者修改初始化的數據,或者程序變得複雜,我需要增加一個表,這時我需要在版本的數字增加,在加載時,纔會對SQLite中的數據庫個更新,這點非常重要,同時參見onUpgrade()的說明 */

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

}

2、和數據庫進行關聯

就如同在MYSQL中進行來數據庫的創建,表格創建和初始數據的填寫,其他的操作一般在Activity中和用戶互動產生。回憶一下我們在Linux環境中如何處理,首先是要創建和數據庫的連接,Android也一樣,另外在Activity結束時,我們需要將連接斷開,以釋放有關資源。

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實例的操作,來進行對數據進行增刪改查詢,採用可寫的方式。
        db= (new Chapter22Db (getApplicationContext())).getWritableDatabase();  
    }

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

3、對錶格進行操作

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

3.1增加一行數據

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

//RAW方式。
db.execSQL("INSERT INTO mytable(Name,Weight) VALUES ('Test1',1.0);");
//API方式,通過db.insert("mytable","Name",<ContentValues values>);來處理,其中ContentValues是用於存儲名稱和數值,對應爲表格的列的名詞和其在行中的數據。
ContentValues values =new ContentValues(2);//ContentValues有兩個數值
values.put("Name", "Test2"); //一個列名爲Name,數據爲Test2
values.put("Weight", 2.0); //一個列名爲Weight,數據爲2.0
db.insert("mytable","Name",values);

3.2刪除一行數據

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

3.3更新一行數據

//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我們可以通過下面的方式來讀取數據:

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

通過Cursor我們可以讀取數據庫的詳細信息,結合到Android學習筆記(二十):迴歸簡單的ListView,我們可以數據用ArrayList<HashMap<>>來存放,由於real非對象,簡單地用ArrayList<HashMap<String,String>>來存儲。我們已經有能力對SQLite數據進行處理,並也有能力處理ListView,這樣可以編寫我們的Activity。

然而Cursor中其實已存有信息,我們也可以使用CursorAdapter來處理,在下一次我們將在這個例子的基礎上,經CursorAdapter和ListView結合給出例子。

發佈了2 篇原創文章 · 獲贊 4 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章