【发布时间】:2021-07-09 08:23:37
【问题描述】:
我的房间数据库如下
@Database(entities = [UserEntity::class], version = 6)
abstract class RoomDB : RoomDatabase() {
abstract fun getDao(): RoomDao
companion object {
private var INSTANCE: RoomDB? = null
val MIGRATION_5_6 = object : Migration(5, 6) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL(
"CREATE TABLE my_table_new (" +
"id INTEGER NOT NULL, " +
"name TEXT, " +
"age INTEGER NOT NULL, " +
"PRIMARY KEY(id))"
)
database.execSQL("INSERT INTO my_table_new (id, name, age) SELECT id, name, 0 FROM my_table")
database.execSQL("DROP TABLE my_table")
database.execSQL("ALTER TABLE my_table_new RENAME TO my_table")
}
}
fun getInstance(context: Context): RoomDB {
if (INSTANCE == null) {
synchronized(RoomDB::class) {
INSTANCE = Room.databaseBuilder(
context.applicationContext,
RoomDB::class.java,
"user.db"
)
.addMigrations(MIGRATION_5_6)
.build()
}
}
return INSTANCE!!
}
}
}
之前的版本是5,这次升级的版本是6。在版本5中没有age列,但是在版本6中新增了。所以如果你看INSERT INTO的声明,你可以看到数字0是强行插入的。从代码中可以看出,我们还编写了 MIGRATION 代码。道是:
@Dao
interface RoomDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(entity: UserEntity)
@Delete
fun delete(entity: UserEntity)
@Query("SELECT * FROM my_table")
fun getUser(): List<UserEntity>
@Query("DELETE FROM my_table")
fun deleteAll()
}
实体看起来像这样:
@Entity(tableName = "my_table")
data class UserEntity(
@ColumnInfo(name = "id")
@PrimaryKey var id: Int,
@ColumnInfo(name = "name")
var name: String,
@ColumnInfo(name = "age")
var age: Int
)
当我在这里调用 getUser() 时,我得到以下异常。
java.lang.IllegalStateException: Room 无法验证数据完整性。看起来您已更改架构但忘记更新版本号。您可以通过增加版本号来解决此问题。
我到底应该如何升级 Room 版本?是不是我做错了什么?
【问题讨论】:
-
您好,您是否在应用的生产版本上测试了迁移?
-
您是指在 Play 商店上架的生产版本吗?此应用程序尚未发布到生产环境。有一些建议说你可以删除并重新安装正在测试的应用程序,但我想要的是升级现有的数据库。
-
如果您的应用未投入生产,那么您可以使用 RoomBuilder 中的 fallbackToDestructiveMigration 方法。
-
fallbackToDestructiveMigration函数被称为永久删除现有数据并创建新表的函数。在我目前正在测试的 Room Database 中,在版本 5 中输入了一些没有age列的数据。如果我使用你提到的功能,我在版本 5 中创建的数据会消失吗?如果是这样,那不是我想要的。
标签: android database android-room