Android Jetpack架构组件-Room升级

  • Jetpack系列文章
  • Android Jetpack架构组件-Lifecycle使用
  • Android Jetpack架构组件-LiveData使用
  • Android Jetpack架构组件-ViewModel的使用及原理
  • Android Jetpack架构组件-Paging介绍及实践
  • Android Jetpack架构组件-Room基本使用
  • Android Jetpack架构组件-Room数据库查询艺术
  • Android Jetpack架构组件-Room升级
  • Android Jetpack架构组件-WorkManager使用篇
  • Android Jetpack架构-Paging自定义上拉加载更多

Android Jetpack架构组件-Room升级_第1张图片

在Android中使用任何一种数据库框架,少不了应用的迭代和数据库的升级,那么Room的该如何正确的升级?

一、Room数据库升级

  • 第一步:增加version数据,及版本号增加
@Database(entities = [Cheese::class, User::class], version = 2, exportSchema = true)
abstract class CheeseDb : RoomDatabase() {
}
  • 第二步:创建Room特有的Migration
      val MIGRATION_1_2: Migration = object : Migration(1, 2) {
            override fun migrate(database: SupportSQLiteDatabase) {
                database.execSQL("ALTER TABLE user ADD COLUMN birthday INTEGER NOT NULL DEFAULT 23 ")
            }
        }

Migration构造函数中,第一个参数代码需要哪个版本才升级,第二个参数,是升级到哪个版本,一般情况和version保持一致

  • 第三步:将Migration添加到配置中,如注释1所示
instance = Room.databaseBuilder(context, CheeseDb::class.java, "onexzgj")
                    .allowMainThreadQueries()
                    .addMigrations(MIGRATION_1_2)  //注释1
                    .build()

到这里,一次完整的数据库升级即可完成

二、Room升级常见错误

  • 1.数据库的vesion未变 ,添加了Migration的crash
Room cannot verify the data integrity. Looks like you've changed schema but forgot to update the version number. 
You can simply fix this by increasing the version number.
  • 2.数据库的version增加,未提供Migration的crash
Caused by: java.lang.IllegalStateException: A migration from 1 to 1 was required but not found.
Please provide the necessary Migration path via RoomDatabase.Builder.addMigration(Migration ...) or 
allow for destructive migrations via one of the RoomDatabase.Builder.fallbackToDestructiveMigration* methods.
  • 3.第二种情况的错误解决
    3.1配置中添加了fallbackToDestructiveMigration()方法,如下所示
    instance = Room.databaseBuilder(context, CheeseDb::class.java, "onexzgj")
                    .allowMainThreadQueries()
                    .fallbackToDestructiveMigration()  //注释1
                    .build()

即在如上代码注释1处添加.fallbackToDestructiveMigration() ,这种方式虽然不会crash,但是数据库的数据会清空
3.2配置中添加Migration,数据库升级成功,且不会清空数据,即按照第一部分正确升级姿势

  • 4、增加字段未设置默认值
.IllegalStateException: Migration didn't properly handle tasks(googleroom.android.com.google_room.data.Task).
     Expected:

如果在定义Migration的时候,添加的是INTEGER类型的字段,则需要设置默认值,如果不设置默认值,即会遇到如上crash

错误Migration示例代码

     val MIGRATION_1_2: Migration = object : Migration(1, 2) {
            override fun migrate(database: SupportSQLiteDatabase) {
                database.execSQL("ALTER TABLE user ADD COLUMN birthday INTEGER")
            }
        }

正确Migration的实例代码

     val MIGRATION_1_2: Migration = object : Migration(1, 2) {
            override fun migrate(database: SupportSQLiteDatabase) {
                database.execSQL("ALTER TABLE user ADD COLUMN birthday INTEGER NOT NULL DEFAULT 23 ")
            }
        }

本文示例代码已上传至Jetpack_Component

你可能感兴趣的:(Android Jetpack架构组件-Room升级)