數(shù)據(jù)庫升級的意義
我們在開發(fā)Android應(yīng)用的時候剪芍,不可避免地要使用數(shù)據(jù)庫岔擂。而數(shù)據(jù)庫的結(jié)構(gòu)在第一版的時候定下來睬辐,之后發(fā)布功能更新,或增加業(yè)務(wù)邏輯症汹,原來的數(shù)據(jù)庫結(jié)構(gòu)可能就不適用了硫朦。而如果數(shù)據(jù)庫的結(jié)構(gòu)與之前版本的結(jié)構(gòu)不同,新版本的應(yīng)用讀取舊數(shù)據(jù)庫肯定會出問題背镇。解決辦法只有兩種:
1.讓用戶卸載老版本再安裝新的程序咬展;
2.軟件自行更新數(shù)據(jù)庫結(jié)構(gòu)。
第一種辦法很明顯不具備可操作性芽世,而且用戶一旦卸載軟件挚赊,數(shù)據(jù)就丟失了,這是不能容忍的事情济瓢。因此荠割,作為開發(fā)者必須妥善處理數(shù)據(jù)庫的升級問題。
當然了旺矾,有的同學會說蔑鹦,這問題沒意義嘛。我們在設(shè)計軟件的時候就把數(shù)據(jù)庫設(shè)計得完備一點就好了箕宙,一開始就考慮周全嚎朽,以后再也不用管升級的事情。這種方法理論上雖然可行柬帕,但實際操作起來是非常困難的哟忍,除非你在開發(fā)定制軟件(例如某些和硬件結(jié)合的產(chǎn)品,其硬件發(fā)布之后就不再更新或很少更新陷寝,這樣的軟件確實沒多大改動)锅很。對于面向市場的應(yīng)用來說,很可能在立項之初根本不會知道以后會增加哪些功能凤跑。這樣爆安,我們終究還是要面對這個問題。
保留數(shù)據(jù)的升級
現(xiàn)在以一個假想的程序數(shù)據(jù)庫來談如何保留原有的數(shù)據(jù)庫進行升級仔引。為直觀起見扔仓,這里在每次軟件版本安裝之后導出了數(shù)據(jù)庫文件褐奥,并使用SQLite Studio顯示表結(jié)構(gòu)和內(nèi)容,過程從略翘簇。并且為了代碼的簡潔撬码,省略了一些異常處理。我們假設(shè)數(shù)據(jù)庫有這樣三個版本:
v1:t_user(username, password);
v2:t_user(username, password),t_region(region, code);
v3:t_user(username, password),t_region(region, code, country);
可以看出缘揪,第一次升級增加了一張表耍群,而第二次升級修改了表的定義。
創(chuàng)建和升級數(shù)據(jù)表的基本知識
我們在使用數(shù)據(jù)庫之前找筝,基本上會自定義一個類繼承自SQLiteOpenHelper蹈垢。該類的其中一個構(gòu)造函數(shù)形式是這樣的(另一個多出來一個DatabaseErrorHandler):
publicSQLiteOpenHelper(Context context, String name,? ? ? ? ? ? ? ? ? ? CursorFactory factory,intversion) {this(context, name, factory, version,null);? ? }
這個構(gòu)造函數(shù)里面的version參數(shù)即是我們設(shè)定的版本號。第一次使用數(shù)據(jù)庫時傳遞的這個版本將被系統(tǒng)記錄袖裕,并調(diào)用SQLiteOpenHelper#onCreate()方法進行建表操作曹抬。后續(xù)傳入的版本如果比這個高,則會調(diào)用SQLiteOpenHelper#onUpgrade()方法進行升級急鳄。
增加一張表
很明顯谤民,增加新表(或者刪除沒有外鍵的表)的操作代價很小,只需要在onUpgrade()中寫好建表操作和插入初始數(shù)據(jù)就好了疾宏。
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {if (oldVersion==1){db.execSQL("CREATETABLEt_region(_idintegerprimarykey"+ "autoincrement, regionvarchar, codevarchar)");//insert data...}}
從上面的圖里可以看到张足,新版本的數(shù)據(jù)庫中已經(jīng)有t_region表了。
修改表定義
SQLite數(shù)庫對ALTER TABLE命令支持非常有限坎藐,只能在表末尾添加列为牍,不能修改列定義,不能刪除已有的列岩馍。那么如果要修改表呢碉咆?我們可以采用臨時表的辦法。具體來說有四步:
將現(xiàn)有表重命名為臨時表蛀恩;