Android升級資料庫的最佳寫法

請叫我東子發表於2015-08-17

版權宣告:本文為博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/u010046908/article/details/47727005

方法: 每一個資料庫版本都會對應一個版本號,當指定的資料庫版本號大於當前資料庫版本號的時候,就會進入到onUpgrade()方法中去執行更新操作。這裡需要為每一個版本號賦予它各自改變的內容,然後在onUpgrade()方法中對當前資料庫的版本號進行判斷,再執行相應的改變就可以了。

接著就讓我們來模擬一個資料庫升級的案例,還是由MyDatabaseHelper類來對資料庫進行管理。第一版的程式要求非常簡單,只需要建立一張Book表,MyDatabaseHelper中的程式碼如下所示:

“id integer primary key autoincrement, ” + “author text, ” + “price real, ” + “pages integer, ” + “name text)”;

public MyDatabaseHelper(Context context, String name, CursorFactory factory, int version) { super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase db) { db.execSQL(CREATE_BOOK); }
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { }
}
不過,幾星期之後又有了新需求,這次需要向資料庫中再新增一張Category表。於是,修改MyDatabaseHelper中的程式碼,如下所示:
public class MyDatabaseHelper extends SQLiteOpenHelper { public static final String CREATE_BOOK = “create table Book (” + “id integer primary key autoincrement, ” + “author text, ” + “price real, ” + “pages integer, ” + “name text)”;

public static final String CREATE_CATEGORY = “create table Category (” + “id integer primary key autoincrement, ” + “category_name text, ” + “category_code integer)”;
public MyDatabaseHelper(Context context, String name,
CursorFactory factory, int version) {
super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase db) { db.execSQL(CREATE_BOOK); db.execSQL(CREATE_CATEGORY);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { switch (oldVersion) {
case 1: db.execSQL(CREATE_CATEGORY);
default: }
}
}
可以看到,在onCreate()方法裡我們新增了一條建表語句,然後又在onUpgrade()方法中新增了一個switch判斷,如果使用者當前資料庫的版本號是1,就只會建立一張Category表。這樣當使用者是直接安裝的第二版的程式時,就會將兩張表一起建立。而當使用者是使用第二版的程式覆蓋安裝第一版的程式時,就會進入到升級資料庫的操作中,此時由於Book表已經存在了,因此只需要建立一張Category表即可。
但是沒過多久,新的需求又來了,這次要給Book表和Category表之間建立關聯,需要在Book表中新增一個category_id的欄位。再次修改MyDatabaseHelper中的程式碼,如下所示:
public class MyDatabaseHelper extends SQLiteOpenHelper {
public static final String CREATE_BOOK = “create table Book (” + “id integer primary key autoincrement, ” + “author text, ” + “price real, ” + “pages integer, ” + “name text, ” + “category_id integer)”;
public static final String CREATE_CATEGORY = “create table Category (”
+ “id integer primary key autoincrement, ” + “category_name text, ”
+ “category_code integer)”;

public MyDatabaseHelper(Context context, String name, CursorFactory factory, int version) { super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase db) { db.execSQL(CREATE_BOOK);
db.execSQL(CREATE_CATEGORY);
}
@Override
case 1:
db.execSQL(CREATE_CATEGORY);
case 2:
db.execSQL(“alter table Book add column category_id integer”);
default: }
}
}
可以看到,首先我們在Book表的建表語句中新增了一個category_id列,這樣當使用者直接安裝第三版的程式時,這個新增的列就已經自動新增成功了。然而,如果使用者之前已經安裝了某一版本的程式,現在需要覆蓋安裝,就會進入到升級資料庫的操作中。在onUpgrade()方法裡,我們新增了一個新的case,如果當前資料庫的版本號是2,就會執行alter命令來為Book表新增一個category_id列。
這裡請注意一個非常重要的細節,switch中每一個case的最後都是沒有使用break的,為什麼要這麼做呢?這是為了保證在跨版本升級的時候,每一次的資料庫修改都能被全部執行到。比如使用者當前是從第二版程式升級到第三版程式的,那麼case 2中的邏輯就會執行。而如果使用者是直接從第一版程式升級到第三版程式的,那麼case 1和case 2中的邏輯都會執行。使用這種方式來維護資料庫的升級,不管版本怎樣更新,都可以保證資料庫的表結構是最新的,而且表中的資料也完全不會丟失了。


相關文章