Android Room數(shù)據(jù)庫(kù)自動(dòng)升級(jí)與遷移的策略
前序
在 Android 應(yīng)用開發(fā)中,Room 是 Google 提供的一個(gè)輕量級(jí)數(shù)據(jù)庫(kù)框架,用于簡(jiǎn)化與 SQLite 的交互。在應(yīng)用的迭代過(guò)程中,數(shù)據(jù)庫(kù)的結(jié)構(gòu)不可避免地會(huì)發(fā)生變化,因此,我們需要為數(shù)據(jù)庫(kù)升級(jí)、降級(jí)以及數(shù)據(jù)遷移制定一套合適的策略。
本文將介紹 Room 數(shù)據(jù)庫(kù)升級(jí)的幾種場(chǎng)景和常見的處理方法,包括手動(dòng)遷移和自動(dòng)遷移的策略。
何時(shí)需要升級(jí)數(shù)據(jù)庫(kù)版本號(hào)?
以下幾種情況會(huì)導(dǎo)致數(shù)據(jù)庫(kù)結(jié)構(gòu)的變更,因此必須升級(jí)數(shù)據(jù)庫(kù)版本號(hào),并處理相應(yīng)的遷移邏輯:
新增或刪除表:當(dāng)我們向數(shù)據(jù)庫(kù)中添加或刪除一張表時(shí),必須升級(jí)版本號(hào),并實(shí)現(xiàn)相應(yīng)的遷移處理邏輯,以確保數(shù)據(jù)的一致性。
新增、刪除或修改字段:當(dāng)對(duì)表中的字段進(jìn)行操作時(shí),例如新增一個(gè)列、刪除或重命名列,必須升級(jí)數(shù)據(jù)庫(kù)版本號(hào),同時(shí)處理好字段的遷移或初始化邏輯。
修改索引或約束:如果為某些字段添加索引,或者對(duì)字段的約束(如非空、唯一等)進(jìn)行修改,同樣需要升級(jí)版本號(hào)。
Room 數(shù)據(jù)庫(kù)遷移策略
Room 提供了多種處理數(shù)據(jù)庫(kù)遷移的方式,開發(fā)者可以根據(jù)項(xiàng)目需求選擇合適的遷移策略:
1. fallbackToDestructiveMigration 刪除數(shù)據(jù)庫(kù)并重建
如果應(yīng)用中的數(shù)據(jù)不重要,或者我們?cè)试S用戶丟失數(shù)據(jù)庫(kù)中的所有數(shù)據(jù),可以使用 fallbackToDestructiveMigration 方法,該方法會(huì)在版本號(hào)發(fā)生變化時(shí)直接刪除數(shù)據(jù)庫(kù)并重建。
private static AppDatabase create(final Context context) { return Room.databaseBuilder( context, AppDatabase.class, "AppDatabase.db") .fallbackToDestructiveMigration() // 自動(dòng)刪除并重建數(shù)據(jù)庫(kù) .build(); }
注意:使用這種方式,所有的舊數(shù)據(jù)都會(huì)被刪除,因此適合那些對(duì)數(shù)據(jù)持久性要求不高的場(chǎng)景。
2. addMigrations 自定義遷移邏輯
當(dāng)需要保留用戶數(shù)據(jù)時(shí),可以通過(guò)自定義 Migration
來(lái)處理數(shù)據(jù)庫(kù)結(jié)構(gòu)變更。例如,給 user
表新增一個(gè) testId
字段:
public static final Migration MIGRATION_2_3 = new Migration(2, 3) { @Override public void migrate(@NonNull SupportSQLiteDatabase database) { // 添加新字段并為其設(shè)置默認(rèn)值 database.execSQL("ALTER TABLE user ADD testId INTEGER DEFAULT 0 NOT NULL"); } };
在數(shù)據(jù)庫(kù)的 Room
實(shí)例構(gòu)建時(shí),將這個(gè)遷移添加到數(shù)據(jù)庫(kù)構(gòu)建器中:
private static AppDatabase create(final Context context) { return Room.databaseBuilder( context, AppDatabase.class, "AppDatabase.db") .addMigrations(MIGRATION_2_3) // 自定義的遷移 .build(); }
優(yōu)點(diǎn):這種方式可以確保在數(shù)據(jù)庫(kù)結(jié)構(gòu)變更時(shí),用戶的數(shù)據(jù)不會(huì)丟失,數(shù)據(jù)遷移可以按照開發(fā)者定義的邏輯進(jìn)行。
3. Room 數(shù)據(jù)庫(kù)自動(dòng)遷移
從 Room 2.4 版本開始,支持自動(dòng)遷移功能,能夠根據(jù)數(shù)據(jù)庫(kù)的 schema
文件自動(dòng)生成遷移邏輯,簡(jiǎn)化了跨版本的升級(jí)工作。在自動(dòng)遷移中,Room 會(huì)自動(dòng)處理字段的增加和刪除,開發(fā)者只需配置好數(shù)據(jù)庫(kù)的 schemaLocation
。
步驟一:配置 room.schemaLocation
在 app/build.gradle
文件中配置注解處理器的參數(shù),以便在編譯時(shí)生成數(shù)據(jù)庫(kù)的 schema
文件:
android { defaultConfig { javaCompileOptions { annotationProcessorOptions { arguments = ["room.schemaLocation": "$projectDir/schemas".toString()] } } } }
編譯時(shí)會(huì)在配置的目錄下生成數(shù)據(jù)庫(kù)版本號(hào)對(duì)應(yīng)的 json 文件 — 主要信息為數(shù)據(jù)庫(kù)相關(guān)信息、相關(guān)表信息,自動(dòng)升級(jí)會(huì)根據(jù)這些信息生成 Migration。升級(jí)方式類似于手動(dòng)升級(jí)的方式。
所有的使用的版本號(hào)對(duì)應(yīng)的 json 文件都不能缺少,否則對(duì)應(yīng)版本的升級(jí)會(huì)出問(wèn)題,若中途進(jìn)行的數(shù)據(jù)庫(kù)的自動(dòng)化升級(jí)遷移,可考慮回退版本,編譯成對(duì)應(yīng)的 json 拷貝過(guò)來(lái)。
app ├── build │ ├── libs │ ├── release │ └── schemas │ └── database.AppDatabase.json │ └── 2.json │ └──.json
步驟二:配置自動(dòng)遷移
Room 允許開發(fā)者定義跨版本的自動(dòng)遷移,例如從 version 1
直接升級(jí)到 version 4
:
@Database( entities = {User.class}, version = 4, autoMigrations = { @AutoMigration(from = 1, to = 2), @AutoMigration(from = 2, to = 3), @AutoMigration(from = 3, to = 4), @AutoMigration(from = 1, to = 4) } ) public abstract class AppDatabase extends RoomDatabase { }
注意:在自動(dòng)遷移中,字段的新增需要設(shè)置 defaultValue
,否則會(huì)報(bào)錯(cuò):
@ColumnInfo(defaultValue = "0") public int testId;
4. Room 跨版本升級(jí)與降級(jí)
Room 也支持順序或跨版本的數(shù)據(jù)庫(kù)升級(jí)。假設(shè)用戶下載的是最新版本的應(yīng)用(版本號(hào)為 4),而數(shù)據(jù)庫(kù)版本從未升級(jí)(還停留在 version 1
),Room 會(huì)自動(dòng)依次執(zhí)行從 version 1
到 version 4
的所有遷移。
如果我們希望加快遷移速度,可以定義一個(gè)從 version 1
直接到 version 4
的遷移邏輯,并通過(guò) addMigrations
方法添加:
public static final Migration MIGRATION_1_4 = new Migration(1, 4) { @Override public void migrate(@NonNull SupportSQLiteDatabase database) { // 自定義跨版本遷移邏輯 database.execSQL("ALTER TABLE user ADD COLUMN testId INTEGER DDEDAQEFAULT 0 NOT NULL"); database.execSQL("ALTER TABLE user ADD COLUMN test INTEGER DEDAQ 0 NOT NULL"); } };
添加遷移到 Room
實(shí)例:
db = Room.databaseBuilder(MyApplication.getInstance(), AppDatabase.class, "AppDatabase.db") .addMigrations(MIGRATION_1_2, MIGRATION_2_3, MIGRATION_3_4, MIGRATION_1_4) .fallbackToDestructiveMigration() // 防止沒(méi)有匹配到的遷移時(shí)崩潰 .build();
通過(guò)這種方式,用戶可以直接從 version 1
升級(jí)到 version 4
,避免了逐個(gè)版本的遷移。
總結(jié)
在 Android 應(yīng)用的開發(fā)中,數(shù)據(jù)庫(kù)的升級(jí)與遷移是不可避免的工作。Room 提供了靈活的數(shù)據(jù)庫(kù)遷移機(jī)制,可以通過(guò)手動(dòng)定義遷移、自動(dòng)生成遷移,或在必要時(shí)重建數(shù)據(jù)庫(kù)。開發(fā)者應(yīng)根據(jù)應(yīng)用的實(shí)際需求選擇合適的升級(jí)方案,以確保用戶數(shù)據(jù)的完整性和系統(tǒng)的穩(wěn)定性。
- 自動(dòng)遷移:適用于簡(jiǎn)單字段的增加、刪除等結(jié)構(gòu)變化。
- 自定義遷移:適合復(fù)雜的數(shù)據(jù)庫(kù)操作,能夠靈活應(yīng)對(duì)各種數(shù)據(jù)庫(kù)結(jié)構(gòu)調(diào)整。
- 重建數(shù)據(jù)庫(kù):適用于數(shù)據(jù)不重要或者允許丟失數(shù)據(jù)的場(chǎng)景。
通過(guò)合理的遷移策略,確保數(shù)據(jù)庫(kù)的穩(wěn)定升級(jí),是提高應(yīng)用質(zhì)量的重要一環(huán)。
以上就是Android Room數(shù)據(jù)庫(kù)自動(dòng)升級(jí)與遷移的策略的詳細(xì)內(nèi)容,更多關(guān)于Android Room自動(dòng)升級(jí)與遷移的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android中的Permission權(quán)限機(jī)制介紹
這篇文章主要介紹了Android中的Permission權(quán)限機(jī)制介紹,本文講解了權(quán)限策略、權(quán)限聲明、權(quán)限請(qǐng)求、獲取權(quán)限等內(nèi)容,需要的朋友可以參考下2015-04-04源碼解析Android Jetpack組件之ViewModel的使用
Jetpack 是一個(gè)豐富的組件庫(kù),它的組件庫(kù)按類別分為 4 類,分別是架構(gòu)(Architecture)、界面(UI)、 行為(behavior)和基礎(chǔ)(foundation)。本文將從源碼和大家講講Jetpack組件中ViewModel的使用2023-04-04Android獲取手機(jī)型號(hào)/系統(tǒng)版本號(hào)/App版本號(hào)等信息實(shí)例講解
本示例獲得手機(jī)型號(hào),系統(tǒng)版本,App版本號(hào)等信息,具體實(shí)現(xiàn)如下,感興趣的朋友可以參考下哈2013-06-06Android獲取驗(yàn)證碼倒計(jì)時(shí)顯示效果
這篇文章主要為大家詳細(xì)介紹了Android獲取驗(yàn)證碼顯示的兩種簡(jiǎn)單實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-10-10Android 自定義view實(shí)現(xiàn)水波紋動(dòng)畫效果
這篇文章主要介紹了 Android 自定義view實(shí)現(xiàn)水波紋動(dòng)畫效果的實(shí)例代碼,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧2017-01-01解決Android studio3.6安裝后gradle Download失敗(構(gòu)建不成功)
這篇文章主要介紹了解決Android studio3.6安裝后gradle Download失敗(構(gòu)建不成功),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03Android應(yīng)用開發(fā)中Fragment與Activity間通信示例講解
這篇文章主要介紹了Android應(yīng)用開發(fā)中Fragment與Activity間通信實(shí)例講解,需要的朋友可以參考下2016-02-02Android四種數(shù)據(jù)存儲(chǔ)的應(yīng)用方式
這篇文章主要介紹了Android四種數(shù)據(jù)存儲(chǔ)的應(yīng)用方式的相關(guān)資料,希望通過(guò)本文能幫助到大家,讓大家理解掌握Android存儲(chǔ)數(shù)據(jù)的方法,需要的朋友可以參考下2017-10-10