Android SQLite數據庫升級的問題


SQLite是Android內置的一個很小的關係型數據庫。SQLiteOpenHelper是一個用來輔助管理數據庫建立和版本升級問題的抽象類。咱們能夠繼承這個抽象類,實現它的一些方法來對數據庫進行自定義操做。下面兩個方法必須重寫:html

  • public void onCreate(SQLiteDatabase db)java

  • public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)sql

另外SQLiteOpenHelper子類在構造實例時必須指定當前數據庫的名稱(name)、版本號(version)。而這裏名稱就決定了數據庫存儲 時的文件名稱,而這裏的版本號與App在AndroidMainfest.xml定義的versionCode沒有絕對關聯。也就是在App更新時若是數 據庫的數據結構沒有發生變化那麼數據庫的版本號則不用增長。數據庫

onCreate:調用時機是用戶首次安裝應用後啓動,或是清除App數據庫文件後啓動。這時能夠在這個函數中完成初始的數據表的建立。數據結構

onUpgrade:調用時機是用戶在作應用更新,覆蓋安裝後啓動,若是新版本中數據庫版本號要比舊版本中的數據庫版本號高則會調用。這時能夠在這個函數完成數據庫版本升級帶來的舊版本的兼容問題,以及數據遷移問題。ide

還有一個通常狀況下不須要重寫,但在應用出現逆向降級(如應用由版本號4降級安裝版本號爲3的包)時必須重寫的方法onDowngrade,若是應用降級覆蓋安裝時沒有重寫該方法則會崩潰。函數

在數據庫版本升級時, 咱們可能會遇到這樣一些狀況:spa

  • 須要擴展一個表的字段sqlite

  • 刪除掉原來表上某個冗餘的字段xml

  • 新建一個表

而處理上面這些問題都要在不損害舊數據庫歷史數據的前提下完成。這裏咱們假設用戶手機上以前安裝的是數據庫版本爲1的包,升級安裝的是數據庫版本號爲2的包。這時咱們要在數據庫版本爲2的包在去處理這些升級邏輯。

首先是擴展一個表的字段在onUpgrade中的實現爲:

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    //舊數據庫版本爲1,才爲表pedant添加一個student_name字段
    if(oldVersion < 2) {
        db.execSQL("ALTER TABLE pedant ADD COLUMN student_name text");
    }
}
 

SQLite對ALTER TABLE的支持是有限的,你能夠在一個存在表上添加一個字段到末尾,或者是改變表的名稱。但若是你想作更復雜的操做,好比刪除一個表已有的字段,就要從新建立這個表並完成數據遷移,而不能使用DROP COLUMN這樣方便的命令了。詳見SQLite Frequently Questions

好比表pedant原來有三個字段a、b、c,如今想刪除c字段,那麼在onUpgrade中寫法以下:

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    //舊數據庫版本爲1,刪除表pedant的c字段
    if(oldVersion < 2) {
        db.beginTransaction();
        try {
            db.execSQL("CREATE TEMPORARY TABLE pe_backup (a, b);");
            db.execSQL("INSERT INTO pe_backup SELECT a, b FROM pedant;");
            db.execSQL("DROP TABLE pedant;");
            db.execSQL("CREATE TABLE pedant(a text, b text);");
            db.execSQL("INSERT INTO pedant SELECT a, b FROM pe_backup;");
            db.execSQL("DROP TABLE pe_backup;");
            db.setTransactionSuccessful();
        } finally {
            db.endTransaction();
        }
    }
}

這樣就既完成了對c字段的刪除也保留了原來表上的數據。

最後一種狀況最簡單直接執行CREATE語句就要能夠了。

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    //舊數據庫版本爲1,建立新表newtb
    if(oldVersion < 2) {
        db.execSQL("CREATE TABLE newtb(a text, b text);");
    }
}
相關文章
相關標籤/搜索