Android 官方数据库Room --- 数据迁移

源文档链接

数据迁移

如果app添加/修改feature时,需要重定义实体类来反映这些变化。当用户更新后,要保留原有数据,特别是不能从服务端复原的数据

Room允许编写Migration类来进行数据迁移。每个Migration类会标明startVersionendVersioh。在运行时,Room会运行每个Migration类中的migrate()方法,使用正确的顺序进行数据迁移

注意:如果没有提供必要的migrations,Room会重建数据库,意味着会失去之前的数据

Room.databaseBuilder(getApplicationContext(), MyDb.class, "database-name")
        .addMigrations(MIGRATION_1_2, MIGRATION_2_3).build();

static final Migration MIGRATION_1_2 = new Migration(1, 2) {
    @Override
    public void migrate(SupportSQLiteDatabase database) {
        database.execSQL("CREATE TABLE `Fruit` (`id` INTEGER, "
                + "`name` TEXT, PRIMARY KEY(`id`))");
    }
};

static final Migration MIGRATION_2_3 = new Migration(2, 3) {
    @Override
    public void migrate(SupportSQLiteDatabase database) {
        database.execSQL("ALTER TABLE Book "
                + " ADD COLUMN pub_year INTEGER");
    }
};

注意:为了保持迁移逻辑按预期运行,请使用完整查询,而不是引用表示查询的常量。

在数据迁移完成后,Room会验证迁移是否正确,如果存在问题,会抛出异常信息

迁移测试

为了保证应用的稳定性,需要对数据迁移进行测试,Room提供了测试仓库。但是,需要将数据库导出才能工作

仓库:android.arch.persistence.room:testing

导出

Room会将数据库的信息导出到JSON文件中,需要在build.gradle中设置room.schemaLocation

android {
    ...
    defaultConfig {
        ...
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = ["room.schemaLocation":
                             "$projectDir/schemas".toString()]
            }
        }
    }
}

应该保存所有的导出JSON文件,以便Room创建老的版本用于测试

添加测试库依赖后,指定JSON文件位置

android {
    ...
    sourceSets {
        androidTest.assets.srcDirs += files("$projectDir/schemas".toString())
    }
}

使用MigrationTestHelper解析JSON文件,

测试用例:

@RunWith(AndroidJUnit4.class)
public class MigrationTest {
    private static final String TEST_DB = "migration-test";

    @Rule
    public MigrationTestHelper helper;

    public MigrationTest() {
        helper = new MigrationTestHelper(InstrumentationRegistry.getInstrumentation(),
                MigrationDb.class.getCanonicalName(),
                new FrameworkSQLiteOpenHelperFactory());
    }

    @Test
    public void migrate1To2() throws IOException {
        SupportSQLiteDatabase db = helper.createDatabase(TEST_DB, 1);

        // db has schema version 1. insert some data using SQL queries.
        // You cannot use DAO classes because they expect the latest schema.
        db.execSQL(...);

        // Prepare for the next version.
        db.close();

        // Re-open the database with version 2 and provide
        // MIGRATION_1_2 as the migration process.
        db = helper.runMigrationsAndValidate(TEST_DB, 2, true, MIGRATION_1_2);

        // MigrationTestHelper automatically verifies the schema changes,
        // but you need to validate that the data was migrated properly.
    }
}
Android RoomAndroid平台上的一个持久化库,用于处理本地数据库的操作。当在应用程序中使用Room时,可能会遇到需要进行数据迁移的情况,例如更改数据库模式或添加新的表。 在Room中进行数据迁移可以通过数据库升级来实现。下面是一些常见的步骤: 1. 在Room的Database类中,使用`@Database`注解来定义你的数据库,并指定`version`属性,表示当前数据库的版本号。 ```kotlin @Database(entities = arrayOf(User::class), version = 2) abstract class AppDatabase : RoomDatabase() { // ... } ``` 2. 创建一个新的数据库版本,并在新版本中进行必要的更改。例如,你可以添加新的实体类或更改现有实体类的结构。 ```kotlin @Database(entities = arrayOf(User::class, Order::class), version = 3) abstract class AppDatabase : RoomDatabase() { // ... } ``` 3. 创建一个用于执行数据库升级的`Migration`对象。`Migration`对象需要实现`Migration`接口,并在`migrate()`方法中定义旧版本到新版本的迁移逻辑。 ```kotlin val MIGRATION_2_3: Migration = object : Migration(2, 3) { override fun migrate(database: SupportSQLiteDatabase) { // 执行数据库迁移操作 } } ``` 4. 在创建Room的`Database`对象时,使用`.addMigrations()`方法将迁移对象添加到构建器中。 ```kotlin val db = Room.databaseBuilder( context.applicationContext, AppDatabase::class.java, "app_database" ) .addMigrations(MIGRATION_2_3) .build() ``` 这样,在应用程序升级时,Room将会自动检测到数据库版本的变化,并执行相应的迁移操作。 需要注意的是,当进行数据库迁移
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值