Android Jetpack組件-Room 數據庫昇級

是芝麻吖 2021-08-15 13:37:10 阅读数:260

本文一共[544]字,预计阅读时长:1分钟~
android jetpack room

這是我參與 8 月更文挑戰的第 12 天,活動詳情查看: 8月更文挑戰

背景

在項目中不可避免的使用數據庫, 而三方框架又是五花八門, 在這中我就選擇了google Jetpack組件中的Room
上篇文章 簡單介紹了一下room @Query注解使用. 前幾篇的文章基本把room的基本功能介紹完了, 但是由於需求的迭代昇級, 有時第一版的數據庫結構不能滿足當前需求, 更改數據庫字段就是涉及到數據庫昇級了

Migration

針對數據庫昇級,room提供了Migration類和addMigrations方法來支持,Migration類源碼如下:

public abstract class Migration {
public final int startVersion;
public final int endVersion;
public Migration(int startVersion, int endVersion) {
this.startVersion = startVersion;
this.endVersion = endVersion;
}
public abstract void migrate(@NonNull SupportSQLiteDatabase database);
}
複制代碼

從源碼上看, Migration只提供了一個構造方法, 從注釋上看, Migration提供新版本和舊版本直接的遷移, 構造方法需要傳兩個參數, 開始版本和結束版本

/** * Creates a new migration between {@code startVersion} and {@code endVersion}. * * @param startVersion The start version of the database. * @param endVersion The end version of the database after this migration is applied. */
複制代碼

實現

這裏我采用的是內部類的方式, 如果為了方便查看已經代碼格式問題, 可以去繼承Migration並實現migrate方法,以從版本1昇級到版本2為例

昇級版本在AppDatabase@Database注解中更改version版本

private static final Migration MIGRATION_1_2 = new Migration(1, 2)
{
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
//執行昇級相關操作
}
};
複制代碼

以此類推,版本2昇級到版本3如下

private static final Migration MIGRATION_2_3 = new Migration(2, 3)
{
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
//執行昇級相關操作
}
};
複制代碼

buildDB時通過addMigrations()方法添加昇級邏輯,如下

addMigrations方法接收的是一個可變參數, 如果需要添加多個昇級邏輯,參數之間用,隔開,.addMigrations(MIGRATION_1_2,MIGRATION_2_3,MIGRATION_3_4,....)

private static AppDatabase buildDB(Context context) {
return Room.databaseBuilder(context, AppDatabase.class, DATABASE_NAME)
.addMigrations(MIGRATION_1_2)
.allowMainThreadQueries()
.build();
}
複制代碼

异常

每昇級一次版本,就需要添加一個Migration邏輯, 如果忘記添加就會拋IllegalStateException异常,這是因為在數據庫昇級時未找到對應的Migration邏輯, 從而導致數據庫昇級失敗, 應用發生Crash. 為了防止這種情况發生, 我們可以通過fallbackToDestructiveMigration()方法來避免,此方法可以在數據庫昇級异常時重新創建數據錶,來避免昇級失敗導致應用發生Crash,但是由於重新創建數據庫,就是導致數據丟失,看需求是什麼樣,再决定要不要添加此方法

private static AppDatabase buildDB(Context context) {
return Room.databaseBuilder(context, AppDatabase.class, DATABASE_NAME)
.fallbackToDestructiveMigration()
.addMigrations(MIGRATION_1_2)
.allowMainThreadQueries()
.build();
}
複制代碼
版权声明:本文为[是芝麻吖]所创,转载请带上原文链接,感谢。 https://gsmany.com/2021/08/20210815133652348U.html