標籤:android style blog http io ar color 使用 sp
我們知道在SQLiteOpenHelper的構造方法:
super(Context context, String name, SQLiteDatabase.CursorFactory factory, int version)
中最後一個參數表示資料庫的版本號碼.當新的版本號碼大於當前的version時會調用方法:
onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
所以我們的重點是在該方法中實現SQLite資料庫版本升級的管理
當我們項目剛開始的時候第一版SQLiteOpenHelper是這樣寫的:
package cc.database;import android.content.Context;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteDatabase.CursorFactory;import android.database.sqlite.SQLiteOpenHelper;/** * Demo描述: * SQLite資料庫版本升級的管理實現 * * 參考資料: * http://blog.csdn.net/guolin_blog * Thank you very much */public class DataBaseOpenHelper extends SQLiteOpenHelper { private final static String DATABASE_NAME="test.db"; private static DataBaseOpenHelper mDataBaseOpenHelper; public static final String CREATE_PERSON= "create table person(personid integer primary key autoincrement,name varchar(20),phone VARCHAR(12))"; public DataBaseOpenHelper(Context context,String name,CursorFactory factory,int version) {super(context, name, factory, version);}//注意://將DataBaseOpenHelper寫成單例的.//否則當在一個for迴圈中頻繁調用openHelper.getWritableDatabase()時//會報錯,提示資料庫沒有執行關閉操作static synchronized DataBaseOpenHelper getDBInstance(Context context) {if (mDataBaseOpenHelper == null) {mDataBaseOpenHelper = new DataBaseOpenHelper(context,DATABASE_NAME,null,1);}return mDataBaseOpenHelper;} @Overridepublic void onCreate(SQLiteDatabase db) {db.execSQL(CREATE_PERSON);}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}}
在幾天之後根據項目需求,需要添加一張student表,於是DataBaseOpenHelper就出現了第二版:
package cc.database;import android.content.Context;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteDatabase.CursorFactory;import android.database.sqlite.SQLiteOpenHelper;public class DataBaseOpenHelper extends SQLiteOpenHelper { private final static String DATABASE_NAME="test.db"; private static DataBaseOpenHelper mDataBaseOpenHelper; public static final String CREATE_PERSON= "create table person(personid integer primary key autoincrement,name varchar(20),phone VARCHAR(12))"; public static final String CREATE_STUDENT= "create table student(studentid integer primary key autoincrement,name varchar(20),phone VARCHAR(12))"; public DataBaseOpenHelper(Context context,String name,CursorFactory factory,int version) {super(context, name, factory, version);}//注意://將DataBaseOpenHelper寫成單例的.//否則當在一個for迴圈中頻繁調用openHelper.getWritableDatabase()時//會報錯,提示資料庫沒有執行關閉操作static synchronized DataBaseOpenHelper getDBInstance(Context context) {if (mDataBaseOpenHelper == null) {//改動1mDataBaseOpenHelper = new DataBaseOpenHelper(context,DATABASE_NAME,null,2);}return mDataBaseOpenHelper;} @Overridepublic void onCreate(SQLiteDatabase db) {db.execSQL(CREATE_PERSON);//改動2db.execSQL(CREATE_STUDENT);}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {//改動3switch (oldVersion) {case 1:db.execSQL(CREATE_STUDENT);default:}}}
較版本一在版本二中有三處修改的地方:
1 版本號碼變成了2
2 在onCreate()方法中添加了代碼db.execSQL(CREATE_STUDENT);建立student表
因為有的使用者根本就沒有第一版本的APP,直接從市場下載了第二版本的App。所以當然會執行onCreate()而不會執行onUpgrade()
3 在onUpgrade()做了處理:當oldVersion為1時調用db.execSQL(CREATE_STUDENT);建立student表
因為有的使用者手機上本來就有第一版本的APP,所以在App升級到第二版本時會執行onUpgrade(),不會執行onCreate()
通過這樣的處理使得不同的情況下使用第二版APP時都會產生student表
又過了一個月,根據項目變更,需要給person表添加一個欄位genderid,於是DataBaseOpenHelper就出現了第三版:
package cc.database;import android.content.Context;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteDatabase.CursorFactory;import android.database.sqlite.SQLiteOpenHelper;public class DataBaseOpenHelper extends SQLiteOpenHelper { private final static String DATABASE_NAME="test.db"; private static DataBaseOpenHelper mDataBaseOpenHelper; //改動1 public static final String CREATE_PERSON= "create table person(personid integer primary key autoincrement,name varchar(20),phone VARCHAR(12)),genderid integer)"; public static final String ALTER_PERSON="alter table person add column genderid integer"; public static final String CREATE_STUDENT= "create table student(studentid integer primary key autoincrement,name varchar(20),phone VARCHAR(12))"; public DataBaseOpenHelper(Context context,String name,CursorFactory factory,int version) {super(context, name, factory, version);}//注意://將DataBaseOpenHelper寫成單例的.//否則當在一個for迴圈中頻繁調用openHelper.getWritableDatabase()時//會報錯,提示資料庫沒有執行關閉操作static synchronized DataBaseOpenHelper getDBInstance(Context context) {if (mDataBaseOpenHelper == null) {//改動2mDataBaseOpenHelper = new DataBaseOpenHelper(context,DATABASE_NAME,null,3);}return mDataBaseOpenHelper;} @Overridepublic void onCreate(SQLiteDatabase db) {db.execSQL(CREATE_PERSON);db.execSQL(CREATE_STUDENT);}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {switch (oldVersion) {case 1:db.execSQL(CREATE_STUDENT);//改動3case 2: db.execSQL(ALTER_PERSON);default:}}}
較版本二在版本三中有三處修改的地方:
1 改變了CREATE_PERSON語句,在改語句中增加了一個欄位genderid
和前面的描述類似,有的使用者第一次安裝該APP時就直接下載了第三版
2 修改版本號碼為3
應對了使用者從第一版本或者第二版本升級到第三版本的情況(見下分析)
3 在onUpgrade()方法中)做了處理:當oldVersion為2時調用 db.execSQL(ALTER_PERSON);修改person表,增加genderid欄位
應對了使用者從第二版本升級到第三版本的情況(見下分析)
注意一個問題:為什麼這裡的switch語句在每個case中沒有break???
這是為了保證跨版本升級的時候每次資料庫的升級都會執行到。
比如從第二版升級到第三版本,那麼case 2會被執行。
比如從第一版直接升級到第三版本,那麼case 1肯定會被調用,由於沒有break所以會穿透switch語句又執行case 2語句繼續升級,從而保證了資料的所有版本中的升級都會被執行到。
SQLite資料庫版本升級的管理實現