標籤:
//此系列博文是《第一行Android代碼》的學習筆記,如有錯漏,歡迎指正!
之前我們為了保證資料庫中的表是最新的,只是簡單地在 onUpgrade()方法中刪除掉了當前所有的表,然後強制重新執行了一遍 onCreate()方法。這種方式在產品的開發階段確實可以用,但是當產品真正上線了之後就絕對不行了。想象以下情境,比如你編寫的某個應用已經成功上線,並且還擁有了不錯的下載量。現在由於添加新功能的原因,使得資料庫也需要一起升級,然後使用者更新了這個版本之後發現以前程式中儲存的本機資料全部丟失了。
所以我們需要進行一些合理的控制,保證在升級資料庫的時候資料不會丟失。我們知道,每一個資料庫版本都會對應一個版本號碼, 當指定的資料庫版本號碼大於當前資料庫版本號碼的時候, 就會進入到 onUpgrade()方法中去執行更新操作。所以我們可以在這裡為每一個版本號碼賦予它各自改變的內容,然後在onUpgrade()方法中對當前資料庫的版本號碼進行判斷,再執行相應的改變就可以了。
下面我們來進入實踐:
一、Mission One: 在資料庫中添加一張Book表
這個比較簡單,MyDatabaseHelper代碼如下:
1 public class MyDatabaseHelper extends SQLiteOpenHelper { 2 public static final String CREATE_BOOK = "create table Book (" 3 + "id integer primary key autoincrement, " 4 + "author text, " 5 + "price real, " 6 + "pages integer, " 7 + "name text)"; 8 public MyDatabaseHelper(Context context, String name, CursorFactory 9 factory, int version) {10 super(context, name, factory, version);11 }12 @Override13 public void onCreate(SQLiteDatabase db) {14 db.execSQL(CREATE_BOOK);15 }16 @Override17 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {18 }19 } View Code
二、Mission Two:向資料庫中再添加一張 Category表
1 public class MyDatabaseHelper extends SQLiteOpenHelper { 2 public static final String CREATE_BOOK = "create table Book (" 3 + "id integer primary key autoincrement, " 4 + "author text, " 5 + "price real, " 6 + "pages integer, " 7 + "name text)"; 8 public static final String CREATE_CATEGORY = "create table Category (" 9 + "id integer primary key autoincrement, "10 + "category_name text, "11 + "category_code integer)";12 13 public MyDatabaseHelper(Context context, String name,CursorFactory factory, int version) {14 super(context, name, factory, version);15 }16 17 @Override18 public void onCreate(SQLiteDatabase db) {19 db.execSQL(CREATE_BOOK);20 db.execSQL(CREATE_CATEGORY);21 }22 23 @Override24 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {25 switch (oldVersion) {26 case 1:27 db.execSQL(CREATE_CATEGORY);28 default:29 }30 }31 }View Code
可以看到,在 onCreate()方法裡我們新增了一條建表語句,然後又在 onUpgrade()方法中添加了一個 switch 判斷,如果使用者當前資料庫的版本號碼是 1,就只會建立一張 Category表。這樣當使用者是直接安裝的第二版的程式時,就會將兩張表一起建立。而當使用者是使用第二版的程式覆蓋安裝第一版的程式時,就會進入到升級資料庫的操作中,此時由於 Book 表已經存在了,因此只需要建立一張 Category表即可。
三、Misson Three:在 Book表中添加一個 category_id 的欄位
1 public class MyDatabaseHelper extends SQLiteOpenHelper { 2 public static final String CREATE_BOOK = "create table Book (" 3 + "id integer primary key autoincrement, " 4 + "author text, " 5 + "price real, " 6 + "pages integer, " 7 + "name text, " 8 + "category_id integer)"; 9 public static final String CREATE_CATEGORY = "create table Category ("10 + "id integer primary key autoincrement, "11 + "category_name text, "12 + "category_code integer)";13 14 public MyDatabaseHelper(Context context, String name,CursorFactory factory, int version) {15 super(context, name, factory, version);16 }17 18 @Override19 public void onCreate(SQLiteDatabase db) {20 db.execSQL(CREATE_BOOK);21 db.execSQL(CREATE_CATEGORY);22 }23 @Override24 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {25 switch (oldVersion) {26 case 1:27 db.execSQL(CREATE_CATEGORY);28 case 2:29 db.execSQL("alter table Book add column category_id integer");30 default:31 }32 }33 }View Code
首先我們在 Book 表的建表語句中添加了一個 category_id 列,這樣當使用者直接安裝第三版的程式時,這個新增的列就已經自動添加成功了。然而,如果使用者之前已經安裝了某一版本的程式, 現在需要覆蓋安裝, 就會進入到升級資料庫的操作中。 在 onUpgrade()方法裡,我們添加了一個新的 case,如果當前資料庫的版本號碼是 2,就會執行 alter命令來為Book 表新增一個 category_id 列。
這裡有一點需要注意:switch 中每一個 case 的最後都是沒有使用 break的。這樣做的原因是為了保證在跨版本升級的時候, 每一次的資料庫修改都能被全部執行到。比如使用者當前是從第二版程式升級到第三版程式的,那麼 case 2中的邏輯就會執行。而如果使用者是直接從第一版程式升級到第三版程式的,那麼 case 1 和 case 2 中的邏輯都會執行。使用這種方式來維護資料庫的升級,不管版本怎樣更新,都可以保證資料庫的表結構是最新的,而且表中的資料也完全不會丟失了。
//End.
Android學習筆記(十八)——再談升級資料庫