Android 數(shù)據(jù)存儲知識梳理(4) - 數(shù)據(jù)庫升級操作的處理策略

一、前言

在項目當(dāng)中使用數(shù)據(jù)庫時,由于需求的增加,因此不可避免地要在原有的數(shù)據(jù)庫當(dāng)中增加新的字段,這時候就要在SQLiteOpenHelperonUpgrade方法進(jìn)行處理,關(guān)于SQLiteOpenHelper的內(nèi)部實現(xiàn)原理,可以參考之前的這篇文章:Android 數(shù)據(jù)存儲知識梳理(1) - SQLiteOpenHelper 源碼解析,今天我們主要介紹當(dāng)數(shù)據(jù)庫的結(jié)構(gòu)更新之后應(yīng)當(dāng)如何操作。

二、示例

首先,我們介紹一下整個需求的背景:

  • 第一個版本:應(yīng)用版本為1.0,設(shè)置數(shù)據(jù)庫的版本號為1,創(chuàng)建表firstTable。
  • 第二個版本:應(yīng)用版本為1.1,由于需求變更,需要創(chuàng)建表secondTable,此時secondTable的表中的字段為column1。
  • 第三個版本:應(yīng)用版本為1.2,由于需求變更,需要在secondTable中新增一列column2。

2.1 第一個版本

在第一個版本時,我們創(chuàng)建一個數(shù)據(jù)表first_table,代碼如下:

public class DBHelper extends SQLiteOpenHelper {

    private static final String TAG = "DBHelper";

    private static final String DB_NAME = "table.db";
    private static final int DB_VERSION = 1;

    private static final String CREATE_FIRST_TABLE = "create table if not exists first_table ("
            + "id integer primary key,"
            + "column1 integer)";

    public DBHelper(Context context) {
        super(context, DB_NAME, null, DB_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        Log.d(TAG, "onCreate");
        db.execSQL(CREATE_FIRST_TABLE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        Log.d(TAG, "oldVersion=" + oldVersion + ",newVersion=" + newVersion);
    }
}

當(dāng)我們第一次安裝該版本的應(yīng)用,此時由于沒有創(chuàng)建過該數(shù)據(jù)庫,因此會走到onCreate方法當(dāng)中:


此時的數(shù)據(jù)庫結(jié)構(gòu)為:

2.2 第二個版本

當(dāng)安裝第二個版本的時候,我們有兩種情況:

  • 用戶數(shù)據(jù)庫中沒有first_table,也就是不存在table.db
  • 用戶數(shù)據(jù)庫中有first_table,也就是table.db的版本號為1

這時候,我們就要對DBHelper修改,和第一個版本相比,修改的地方如紅框所示:


針對前面說到的兩種情況,整個執(zhí)行的過程為:

  • 沒有安裝或者運(yùn)行過第一個版本,執(zhí)行的onCreate,不執(zhí)行onUpgrade,這時候就會創(chuàng)建兩個表:
  • 安裝過第一個版本并且運(yùn)行,執(zhí)行onUpgrade,不執(zhí)行onCreate

    此時的數(shù)據(jù)庫結(jié)構(gòu)為:

2.3 第三個版本

前面兩步都沒有問題,那么接下來就是安裝第三個版本,在第三個版本中我們需要在second_table中增加一個新的字段column2,那么這時候就有以下三種情況:

  • 用戶的數(shù)據(jù)庫中沒有任何一個表,即不存在table.db。
  • 用戶的數(shù)據(jù)庫中只有first_table,table.db的版本為1。
  • 用戶的數(shù)據(jù)庫中有first_tablesecond_table,table.db的版本號為2。

因此,我們就要對DBHelper類進(jìn)行如下的修改:


針對于上面談到的三種情況,執(zhí)行的流程分別為:

  • 只執(zhí)行onCreate方法,直接創(chuàng)建帶有column1/column2second_table。
  • 只執(zhí)行onUpgrade方法,因為我們的oldVersion1,因此先走到第一個case語句,創(chuàng)建帶有column1second_table,由于該case語句沒有break,因此接著會走到第二個case語句,在second_table中增加column2列。
  • 只執(zhí)行onUpgrade方法,此時的oldVersion2,因此會直接執(zhí)行第二個case語句,新增column2列。

此時的數(shù)據(jù)庫結(jié)構(gòu)為:


三、小結(jié)

以上就是對于數(shù)據(jù)庫進(jìn)行修改后的更新策略,每更新一個版本之后,我們需要做以下幾件事:

  • 將數(shù)據(jù)庫版本加1。
  • onCreate方法中,定義創(chuàng)建數(shù)據(jù)庫表的語句,它對應(yīng)于表的最新結(jié)構(gòu)。
  • onUpgradeswitch方法的最后,新增一條case語句,該case語句的內(nèi)容為其相對于上個數(shù)據(jù)庫版本所要進(jìn)行的變更操作。

更多文章,歡迎訪問我的 Android 知識梳理系列:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容