一、前言
在項目當(dāng)中使用數(shù)據(jù)庫時,由于需求的增加,因此不可避免地要在原有的數(shù)據(jù)庫當(dāng)中增加新的字段,這時候就要在SQLiteOpenHelper的onUpgrade方法進(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_table、second_table,table.db的版本號為2。
因此,我們就要對DBHelper類進(jìn)行如下的修改:

針對于上面談到的三種情況,執(zhí)行的流程分別為:
- 只執(zhí)行
onCreate方法,直接創(chuàng)建帶有column1/column2的second_table。 - 只執(zhí)行
onUpgrade方法,因為我們的oldVersion為1,因此先走到第一個case語句,創(chuàng)建帶有column1的second_table,由于該case語句沒有break,因此接著會走到第二個case語句,在second_table中增加column2列。 - 只執(zhí)行
onUpgrade方法,此時的oldVersion為2,因此會直接執(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)。 - 在
onUpgrade的switch方法的最后,新增一條case語句,該case語句的內(nèi)容為其相對于上個數(shù)據(jù)庫版本所要進(jìn)行的變更操作。
更多文章,歡迎訪問我的 Android 知識梳理系列:
- Android 知識梳理目錄:http://www.itdecent.cn/p/fd82d18994ce
- 個人主頁:http://lizejun.cn
- 個人知識總結(jié)目錄:http://lizejun.cn/categories/


