在android開發中,app版本疊代過多,不可避免的有Sqlite資料庫更新和降級的操作.當我們通過SqliteOpenHelper獲得一個SqliteDatabase執行個體的時候,他内部會判斷版本号, 調用對應的更新操作和降級操作.抽象類的更新回調方法是一個抽象方法, 降級回調方法直接抛出一個RuntimeException異常.是以,碰到這個問題我們要注意複寫更新和降級的邏輯.
我們以更新為例,假設在本10000是初試版本建立一個person表,裡面有name age local 三個字段,在10010版本增加一個phone字段,在10020版本将local字段改為country字段
我們首先要明确以下問題:
1,android中Sqlite資料庫提供給資料表增加字段功能,但是不同删除字段和更改字段名稱的功能. 是以要删除表字段和更改表字段名稱需要進行資料遷移
2, 要考慮平滑更新
例如:10000可以直接平滑更新到10010,還要考慮到 10000跨版本平滑更新到10020
3,更新過程涉及到資料的遷移 ,可能資料量比較大也比較複雜,是以我們要開啟事務,要麼成功要麼失敗復原
4,一個資料表的遷移步驟為
A,建立一個要更改字段的原來了的資料表名稱更改
B,建立一個新表,新的字段,表明與原表一緻
C,将舊表的資料遷移到新表
D,删除舊表
實作上面需求的代碼如下:
public class DBHelper extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = ;
private static final String DATABASE_NAME = "demo.db";
// 初試版本(第一個版本)建立一張表
private static final String SQL_CREATE_PERSON_TABLE = "CREATE TABLE person (name TEXT, age TEXT, loacal TEXT)";
public DBHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(SQL_CREATE_PERSON_TABLE);
}
// 在資料庫更新和降級的時候,建議開啟事務,這樣要成功都成功,不成功就全不成功,維持現狀,這樣避免髒資料
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// 第二個版本給初始表加一個字段phone
if (oldVersion == ) {
String sql = "ALTER TABLE person ADD phone TEXT";
db.execSQL(sql);
Log.i("tag", "版本更新了 " + "oldVersion = " + oldVersion+ " newVersion = " + newVersion);
//重新設定oldVersion為了跨版本的平滑更新
oldVersion = ;
}
/*
* 第三個版本給person表中的local字段改名為country 由于sqlite資料庫不支援對表中字段名的删除,
* 更名.是以我們需要重新建立一張表, 把原表中的資料備份過去,然後将原表删除即可
*/
if (oldVersion == ) {
Log.i("tag", "版本更新了 " + "oldVersion = " + oldVersion
+ " newVersion = " + newVersion);
String alterTableSql = "alter table person rename to tempPerson";
String createNewTableSql = "create table person (name TEXT, age TEXT, country TEXT,phone TEXT) ";
// step 1:原表person更名為tempPerson
db.execSQL(alterTableSql);
// step 2: 建立新的person表
db.execSQL(createNewTableSql);
// step 3: 原來表的資料遷移到新表
String backupSql = "insert into person select * from tempPerson ";
db.execSQL(backupSql);
// step 4: 删除臨時表 tempPerson
String deleteSql = "DROP table tempPerson";
db.execSQL(deleteSql);
}
}
}
下面給出源碼連結, 當使用demo測試的時候,隻需要将版本号使用10000,10010,10020更改即可
android sqlite資料庫平滑更新demo