Android中的SQLite使用學習

jopen 12年前發布 | 45K 次閱讀 Android Android開發 移動開發

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我們可以讀取數據庫的詳細信息我們可以數據用ArrayList<HashMap<>>來存放,由于real非對象,簡單地用 ArrayList<HashMap<String,String>>來存儲。我們已經有能力對SQLite數據進行處理,并也有能力處理ListView,這樣可以編寫我們的Activity。

來自:http://blog.csdn.net/flowingflying/article/details/6841070

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!