了解Room框架的使用
Android Jetpack架构组件-Room基本使用
Android Jetpack架构组件-Room数据库查询艺术
Android Jetpack架构组件-Room升级
在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 ")
}
}
网友评论