正常我們在開發中經常會遇到sqlite數據庫升級的問題,比如增加字段/刪除字段/表結構重構等等,隨着apk版本的升高,不同版本可能需要對數據庫進行修改,但是要求是數據庫升級不能影響用戶的已存數據,所以今天就來看看數據庫升級流程是怎樣的。
目錄
-
SQLiteDatabase源碼調用流程
- 首先我們需要繼承 SQLiteOpenHelper, 下面是 SQLiteOpenHelper 的源碼註釋:
SQLiteOpenHelper is a helper class to manage database creation and version management.
然後會提示讓我們去重寫他的三個方法:
public SQLiteOpenHelper(@Nullable Context context, @Nullable String name,
@Nullable CursorFactory factory, int version) {
this(context, name, factory, version, null);
// 傳入我們的數據庫名稱 和 版本號version
}
@Override
public void onCreate(SQLiteDatabase db) {
// 創建表
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// 版本升級
}
2. 分析以下上述三個方法調用的時機,何時會被調用。
- 構造方法--首先我們創建數據庫操作類的時候先走構造方法,通過構造方法會把數據庫名稱和版本號 傳 SQLiteOpenHelper
當然這只是創建了,數據庫操作類,數據庫還沒有創建。 - onCreate() 方法是創建表的,只有第一次纔會走這個方法,首次創建數據庫的時候纔會走,之後就不會走了。
- onUpgrade()數據庫升級,這個方法只有構造方法中傳的版本號發生了升級纔會走,所以我們升級的邏輯就在這裏處理。
以上只是常用的方法,還有數據庫降級等等方法按需重寫。
3. 方法調用的源碼流程圖
根據這個流程圖配合我們的源碼更容易理解 sqlite 整個創建流程,這就是整個數據庫版本檢測和獲得db的過程。對整個流程熟悉了之後,接下來我們就好理解數據庫升級。
-
數據庫自動升級流程
對於升級我們就舉一個例子,從db version 1 升級到db version 2的過程:
假如我們的表結構是這樣的
* version = 1;
* auto integer REAL REAL
* _id color loc_x loc_y
* version = 2; 添加了一個 字段 time
* auto integer REAL REAL REAL
* _id color loc_x loc_y time
通過分析源碼我們知道數據庫升級是在 onUpgrade() 方法中的,接下來分析升級流程:
- 創建臨時緩存表 用於緩存老表裏面的數據
- 查詢老表中的數據並且把數據插入到緩存的表中去
- 刪除老表,創建新的表結構
- 把緩存表數據重新插入到新的表結構中去
- 調用查詢,插入檢測是否升級成功
- 升級結束
整個流程就這些,接下來把升級的代碼貼上,特別要注意的是升級的流程要放到子線程中去!
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//創建臨時緩存表 用於緩存老表裏面的數據
String createTable = "CREATE TABLE " + snapCachedTableName
+ " (" + CustomColorEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ CustomColorEntry.COLUMN_NAME_COLOR + " INTEGER,"
+ CustomColorEntry.COLUMN_NAME_LOCX + " REAL,"
+ CustomColorEntry.COLUMN_NAME_LOCY + " REAL)";
db.execSQL(createTable);
//查詢所有的老表數據
List<CustomColor> colors = getCustomColors(CustomColorEntry.TABLE_NAME,db);
//把數據插入到緩存的表中去
for (CustomColor color : colors){
insertCustomColor(color, snapCachedTableName,db);
}
db.execSQL("drop table " + CustomColorEntry.TABLE_NAME);
//創建新的表結構
String createNewTable = "CREATE TABLE " + CustomColorEntry.TABLE_NAME
+ " (" + CustomColorEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ CustomColorEntry.COLUMN_NAME_COLOR + " INTEGER,"
+ CustomColorEntry.COLUMN_NAME_LOCX + " REAL,"
+ CustomColorEntry.COLUMN_NAME_LOCY + " REAL,"
+ CustomColorEntry.COLUMN_NAME_TIME + " REAL)";
db.execSQL(createNewTable);
//查詢所有的緩存表中的數據
List<CustomColor> cachedColors = getCustomColors(snapCachedTableName,db);
//把數據插入到新的表中去
for (CustomColor color : cachedColors){
insertCustomColor(color, CustomColorEntry.TABLE_NAME,db);
}
db.execSQL("drop table " + snapCachedTableName);
}
傳送門github:https://github.com/WangRain1/DbUpgradeDemo 大家給點支持,笑嘻嘻