以前在安卓端使用數(shù)據(jù)庫存儲(chǔ)數(shù)據(jù)時(shí),總是不可避免地后期涉及到數(shù)據(jù)庫升級(jí)的問題,在早期Room版本中,需要編寫對(duì)應(yīng)的sql文件來處理對(duì)應(yīng)版本升級(jí)的問題,這樣很容易出現(xiàn)問題,比如少寫了某些字段的處理,這些問題造成的后果就是APP崩潰閃退
private static Migration migration1_2 = new Migration(1, 2) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
database.execSQL("ALTER TABLE Repo"
+ " ADD COLUMN age INTEGER ");
}
};
private static RepoDatabase create(final Context context) {
return Room.databaseBuilder(
context,
RepoDatabase.class,
DB_NAME)
.addMigrations(migration1_2)
.build();
}
// 修改版本號(hào)
@Database(entities = Repo.class, version = 2)
可能大多數(shù)人都遇到過,我就在線上環(huán)境出現(xiàn)過這種問題,結(jié)果就不用說了,哈哈
后來,在2.4.0版本開始,room加入了一項(xiàng)重要功能------自動(dòng)遷移,專門用于簡化數(shù)據(jù)庫升級(jí)的問題,最大程度避免了數(shù)據(jù)庫升級(jí)過程中存在的各種問題,簡直不要太好用
具體使用步驟:
- 首先,你需要把room版本升級(jí)為至少2.4.0
//Room數(shù)據(jù)庫: https://developer.android.google.cn/jetpack/androidx/releases/room
def room_version = "2.4.0"
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
implementation "androidx.room:room-ktx:$room_version"
- 增加schemas文件輸出配置,這個(gè)是用來生成每個(gè)數(shù)據(jù)庫版本對(duì)應(yīng)的數(shù)據(jù)庫結(jié)構(gòu)文件,在自動(dòng)遷移數(shù)據(jù)庫的時(shí)候就是根據(jù)這個(gè)結(jié)構(gòu)的差異,來進(jìn)行自動(dòng)遷移處理的,配置完之后,運(yùn)行項(xiàng)目,會(huì)在對(duì)應(yīng)的目錄下生成對(duì)應(yīng)數(shù)據(jù)庫版本的文件,這些記得保存,不要改動(dòng)(千萬不要改動(dòng))
defaultConfig {
......
javaCompileOptions {
annotationProcessorOptions {
arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
}
}
}
- 如果有數(shù)據(jù)庫結(jié)構(gòu)變動(dòng),則修改對(duì)應(yīng)的數(shù)據(jù)庫版本,并添加自動(dòng)升級(jí)配置,比如從1升級(jí)到2,那就吧version改為2,并添加 AutoMigration(from = 1, to = 2)
@Database(entities = [Inspiration::class, Daiban::class, SportClass::class, SportLog::class], version = 3, autoMigrations = [
AutoMigration(from = 1, to = 2),
AutoMigration(from = 2, to = 3),
])
abstract class AppDataBase : RoomDatabase() {
abstract fun inspirationDao(): InspirationDao
abstract fun daibanDao(): DaibanDao
abstract fun sportDao(): SportDao
}
至此自動(dòng)化遷移工作就完成了,就是這么簡單,裝個(gè)數(shù)據(jù)庫版本為1的app,然后用新版本覆蓋,數(shù)據(jù)庫就會(huì)自動(dòng)完成遷移配置
可能遇到的問題:
在開發(fā)過程中因?yàn)闀?huì)頻繁修改數(shù)據(jù)庫,所以,如果出現(xiàn)數(shù)據(jù)庫字段遷移問題的話,就直接卸載重新安裝就可以了,不用頻繁修改version,但是在上線前一定要檢查數(shù)據(jù)庫自動(dòng)遷移是否正常,避免把問題暴露在生產(chǎn)環(huán)境中,具體驗(yàn)證方式就是手機(jī)上先安裝前一個(gè)版本的上線包,然后運(yùn)行即將上線的新版本代碼覆蓋舊版本,檢查數(shù)據(jù)庫文件是否正常遷移,如果存在問題則針對(duì)具體的問題進(jìn)行修復(fù)
最后,提供一個(gè)走投無路的操作,如果數(shù)據(jù)不是特別重要的話,可以開啟破壞性重建fallbackToDestructiveMigration,避免APP崩潰至于具體作用,大家就看文檔注釋吧,這是一個(gè)下下策,慎用
Room.databaseBuilder(context, AppDataBase::class.java, "Record_Things_db")
.fallbackToDestructiveMigration()
.build()