头图

Easily move database tables between different

Since the 2.4.0-alpha01 version, the automatic migration function has been newly added to the Room library, which makes the implementation of database migration easier. In the past, whenever your database schema changed, you had to implement a Migration class and inform Room of the actual change, and in most cases it involved writing and executing complex SQL queries.

Now, with the automatic migration function, you can specify which version to migrate from. Room can automatically generate migration programs for simple situations, such as adding or deleting columns and creating new database tables. But in ambiguous scenarios, Room needs some help. You can provide specific specifications—such as renaming or deleting columns/database tables—based on this, and Room will generate and run migration actions for you. Next, let us look at some examples and specific performance!

Add automatic elements to the automatic migration

For example, we need to add a new column to a table in the database and upgrade the database from version 1 to version 2. Then we need to update the @Database annotation to its incremental version number, and add an automatic migration from version 1 to 2:

/* Copyright 2020 Google LLC.  
   SPDX-License-Identifier: Apache-2.0 */

@Database(
-   version = 1,
+   version = 2,
    entities = [ Doggos.class ],
+   autoMigrations = [
+         AutoMigration (from = 1, to = 2)
+     ]
  )
abstract class DoggosDatabase : RoomDatabase { }

Whenever the database version changes again, you only need to update the autoMigrations list and add a new one:

/* Copyright 2020 Google LLC.  
   SPDX-License-Identifier: Apache-2.0 */

@Database(
-   version = 2,
+   version = 3,
    entities = [ Doggos.class ],
    autoMigrations = [
       AutoMigration (from = 1, to = 2),
+      AutoMigration (from = 2, to = 3)
     ]
  )
abstract class DoggosDatabase : RoomDatabase { }

For entities declared in the @Database schema, such as adding new columns or tables, updating primary keys, foreign keys or indexes, or changing the default values of columns, Room will automatically detect these changes without additional intervention.

⚠️ Please note: from the implementation level,, Room automatic migration is dependent on the generated database schema, so use autoMigrations , make sure @Database in exportSchema options true . Otherwise it will cause an error: Cannot create auto-migrations when export schema is OFF .

When help is needed for automatic migration

The automatic migration of Room cannot detect all possible changes performed on the database, so sometimes they need some help. For a common example, Room cannot detect whether a database table or column has been renamed or deleted. In this case, Room will throw a compilation error and ask you to implement AutoMigrationSpec. This class allows you to specify the type of change to be made, implement an AutoMigrationSpec and annotate it with one or more of the following:

  • @DeleteTable(tableName)
  • @RenameTable(fromTableName, toTableName)
  • @DeleteColumn(tableName, columnName)
  • @RenameColumn(tableName, fromColumnName, toColumnName)

For example, suppose we Doggos the database table of GoodDoggos . Room cannot detect whether we created this table and deleted the Doggos table, or renamed it and want to keep all the values.

/* Copyright 2020 Google LLC.  
   SPDX-License-Identifier: Apache-2.0 */

@Database(
   version = 2,
   entities = [ GoodDoggos.class ],
   autoMigrations = [
        AutoMigration (
            from = 1, 
            to = 2,
            spec = DoggosDatabase.DoggosAutoMigration::class
       )
    ]
)
abstract class DoggosDatabase : RoomDatabase {   
  @RenameTable(fromTableName = "Doggos", toTableName = "GoodDoggos")
    class DoggosAutoMigration: AutoMigrationSpec {   }
}

migration vs automatic migration

When to use the migration function

For manual migration of databases ( manually handle migrations ), Room has provided Migration since version 1.0. Whenever you want to change a complex database schema, you have to use this class. For example, if we decide to split a table in the database into two different tables, Room cannot detect the execution of the split, nor can it automatically detect the data that needs to be moved. Therefore, at this time, you need to implement a Migration class and add it to the databaseBuilder() through the addMigrations() method.

/* Copyright 2020 Google LLC.  
   SPDX-License-Identifier: Apache-2.0 */

val MIGRATION_1_2 = object : Migration(1, 2) {
    override fun migrate(database: SupportSQLiteDatabase) {
        ...
    }
}

Room.databaseBuilder(applicationContext, DoggosDatabase::class.java, "doggos-database")
    .addMigrations(MIGRATION_1_2,)
    .build()

Combine "migration" and "

Room allows the use of a combination of migration and automatic migration. For example, migrating from version 1 to version 2 can be done through Migration, and migrating from version 2 to 3 can use automatic migration. If you define both Migration and automatic migration on the same version, only Migration will take effect.

In the underlying implementation, automatic migration will build a Migration class, so the migration logic detailed in article TL;DR: When the database is accessed for the first time, Room will check whether the current database version is different from the version defined in @Database. If so, Room will find a migration path from one to the other, and then continue to perform migration operations.

Test automatic migration

You can test the automatic migration through the test rules of MigrationTestHelper, and call helper.runMigrationsAndValidate() in the same way as using the Migration class. For more information about the test migration, you are welcome to view the document: Test a single migration .

Summary

The automatic migration function ( @Database parameter in autoMigration ) allows you to easily cope with database schema changes. Although Room can handle many basic situations, you still need to implement a AutoMigrationSpec for deleting or renaming database tables/columns. For other situations, please continue to use Migrations .

This feature is still in the alpha status, and you are welcome issue tracker to help us do better.


Android开发者
404 声望2k 粉丝

Android 最新开发技术更新,包括 Kotlin、Android Studio、Jetpack 和 Android 最新系统技术特性分享。更多内容,请关注 官方 Android 开发者文档。