美文网首页
(四)迁移Room数据库

(四)迁移Room数据库

作者: 鹿小纯0831 | 来源:发表于2018-10-31 09:11 被阅读2次

    在应用程序中添加和更改功能时,需要修改实体类以反映这些更改。 当用户更新到最新版本的应用程序时,您不希望它们丢失所有现有数据,尤其是在您无法从远程服务器恢复数据时。
    Room persistence库允许您编写Migration类以此方式保留用户数据。 每个Migration类都指定一个startVersionendVersion。 在运行时,Room运行每个Migration类的migrate()方法,使用正确的顺序将数据库迁移到更高版本。

    警告:如果您未提供必要的迁移,则会重建数据库,这意味着您将丢失数据库中的所有数据。

    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发现问题,则会抛出包含不匹配信息的异常。

    测试迁移

    迁移并不容易编写,如果无法正确编写它们可能会导致应用程序出现崩溃循环。 为了保持应用程序的稳定性,您应该事先测试迁移。 Room提供测试Maven工件以协助此测试过程。 但是,要使此工件生效,您需要导出数据库的架构。

    导出模式

    编译后,Room会将数据库的架构信息导出到JSON文件中。 要导出架构,请在build.gradle文件中设置room.schemaLocation注释处理器属性,如以下代码段所示:

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

    您应该在版本控制系统中存储导出的JSON文件(表示数据库的架构历史记录),因为它允许Room创建数据库的旧版本以进行测试。

    要测试这些迁移,请将Room.arch.persistence.room:测试Maven工件从Room添加到测试依赖项中,并将架构位置添加为资产文件夹,如以下代码段所示:

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

    测试包提供了MigrationTestHelper类,可以读取这些模式文件。 它还实现了JUnit4 TestRule接口,因此它可以管理创建的数据库。

    以下代码段中显示了示例迁移测试:

    @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.
        }
    }
    

    相关文章

      网友评论

          本文标题:(四)迁移Room数据库

          本文链接:https://www.haomeiwen.com/subject/qcyotqtx.html