更改了房间中的数据类型,如何进行迁移?
Changed data-type in room, how to do a migration?
我已将一个列类型从 Float 更改为 Int,如何迁移更改以免丢失旧条目,而只是将它们全部转换为 Int。
您需要添加一个 Migration,它将以新形式创建 table 并从旧形式复制数据。
新表单的 SQL 可以通过查看生成的 java 来确定(从 Android Studio 的 Android 视图可见)。查看与@Database注解但后缀为_Impl的class同名的class,然后找到SQL在名为 createAllTables
的方法中
然后您可以使用以下内容
:-
- DROP,以防中间旧 table 例如
DROP TABLE IF EXISTS table_old;
- 根据
ALTER TABLE the_table RENAME TO the_table_old;
使用 SQL 重命名原始 table
- 使用上面获得的SQL创建新的table
- 根据
INSERT INTO the_table SELECT * FROM the_table_old;
使用SQL复制数据
- 删除现在已经不存在的旧 table 例如
DROP TABLE IF EXISTS table_old;
;
演示
举个例子,实体是(被注释掉了):-
@Entity(tableName = "jourTable")
class Note(
@ColumnInfo(name = "title") val jourTitle:String,
@ColumnInfo(name = "description") val jourDescription:String,
@ColumnInfo(name = "date") val jourDate:String,
@ColumnInfo(name = "image", typeAffinity = ColumnInfo.BLOB) val jourImage: Bitmap?, //<<<<< will use the TypeConverter
//@ColumnInfo(name = "altImage") val jourAltImage: ByteArray //<<<<< will not use the TypeConverter
@ColumnInfo(name = "altImage") val jourAltImage: Int
) {
@PrimaryKey(autoGenerate = true)var id=0
}
- 即注释掉 jourAltImage was ByteArray now to be Int (INTEGER type in SQL)
生成的java是通过:-
获得的
@Database 注解class (TheDatabase) 有:-
@TypeConverters(ImageConverter::class)
@Database(entities = [Note::class], version = 2 /*<<<<<<<<<< INCREASE FROM 1 to 2 (or as required)*/, exportSchema = false)
abstract class TheDatabase: RoomDatabase() {
abstract fun getAllDao(): AllDao
companion object {
@Volatile
private var instance: TheDatabase ? = null
fun getInstance(context: Context): TheDatabase {
if (instance == null) {
instance = Room.databaseBuilder(context,TheDatabase::class.java,"the_database.db")
.allowMainThreadQueries()
.addMigrations(MIG_1_2) //<<<<<<<<<< ADD the migration
.build()
}
return instance as TheDatabase
}
/*<<<<<<<<<< The Migration >>>>>>>>>> */
val MIG_1_2 = object: Migration(1,2){
override fun migrate(db: SupportSQLiteDatabase) {
db.execSQL("DROP TABLE IF EXISTS jourTable_old;")
db.execSQL("ALTER TABLE jourTable RENAME TO jourTable_old ")
/* SQL ON NEXT LINE COPIED FROM GENERATED JAVA */
db.execSQL("CREATE TABLE IF NOT EXISTS `jourTable` (`title` TEXT NOT NULL, `description` TEXT NOT NULL, `date` TEXT NOT NULL, `image` BLOB, `altImage` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)")
db.execSQL("INSERT INTO jourTable SELECT * FROM jourTable_old")
db.execSQL("DROP TABLE IF EXISTS jourTable_old")
}
}
}
}
当 运行 应用程序检查显示(它有 1 行)并且应用程序在 运行 时添加 1 新行:-
- 正如 cab 所见,altimage 列现在是 INTEGER(是 BLOB)并且保留了第 1 行。
我已将一个列类型从 Float 更改为 Int,如何迁移更改以免丢失旧条目,而只是将它们全部转换为 Int。
您需要添加一个 Migration,它将以新形式创建 table 并从旧形式复制数据。
新表单的 SQL 可以通过查看生成的 java 来确定(从 Android Studio 的 Android 视图可见)。查看与@Database注解但后缀为_Impl的class同名的class,然后找到SQL在名为 createAllTables
的方法中然后您可以使用以下内容
:-
- DROP,以防中间旧 table 例如
DROP TABLE IF EXISTS table_old;
- 根据
ALTER TABLE the_table RENAME TO the_table_old;
使用 SQL 重命名原始 table
- 使用上面获得的SQL创建新的table
- 根据
INSERT INTO the_table SELECT * FROM the_table_old;
使用SQL复制数据
- 删除现在已经不存在的旧 table 例如
DROP TABLE IF EXISTS table_old;
;
演示
举个例子,实体是(被注释掉了):-
@Entity(tableName = "jourTable")
class Note(
@ColumnInfo(name = "title") val jourTitle:String,
@ColumnInfo(name = "description") val jourDescription:String,
@ColumnInfo(name = "date") val jourDate:String,
@ColumnInfo(name = "image", typeAffinity = ColumnInfo.BLOB) val jourImage: Bitmap?, //<<<<< will use the TypeConverter
//@ColumnInfo(name = "altImage") val jourAltImage: ByteArray //<<<<< will not use the TypeConverter
@ColumnInfo(name = "altImage") val jourAltImage: Int
) {
@PrimaryKey(autoGenerate = true)var id=0
}
- 即注释掉 jourAltImage was ByteArray now to be Int (INTEGER type in SQL)
生成的java是通过:-
获得的@Database 注解class (TheDatabase) 有:-
@TypeConverters(ImageConverter::class)
@Database(entities = [Note::class], version = 2 /*<<<<<<<<<< INCREASE FROM 1 to 2 (or as required)*/, exportSchema = false)
abstract class TheDatabase: RoomDatabase() {
abstract fun getAllDao(): AllDao
companion object {
@Volatile
private var instance: TheDatabase ? = null
fun getInstance(context: Context): TheDatabase {
if (instance == null) {
instance = Room.databaseBuilder(context,TheDatabase::class.java,"the_database.db")
.allowMainThreadQueries()
.addMigrations(MIG_1_2) //<<<<<<<<<< ADD the migration
.build()
}
return instance as TheDatabase
}
/*<<<<<<<<<< The Migration >>>>>>>>>> */
val MIG_1_2 = object: Migration(1,2){
override fun migrate(db: SupportSQLiteDatabase) {
db.execSQL("DROP TABLE IF EXISTS jourTable_old;")
db.execSQL("ALTER TABLE jourTable RENAME TO jourTable_old ")
/* SQL ON NEXT LINE COPIED FROM GENERATED JAVA */
db.execSQL("CREATE TABLE IF NOT EXISTS `jourTable` (`title` TEXT NOT NULL, `description` TEXT NOT NULL, `date` TEXT NOT NULL, `image` BLOB, `altImage` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)")
db.execSQL("INSERT INTO jourTable SELECT * FROM jourTable_old")
db.execSQL("DROP TABLE IF EXISTS jourTable_old")
}
}
}
}
当 运行 应用程序检查显示(它有 1 行)并且应用程序在 运行 时添加 1 新行:-
- 正如 cab 所见,altimage 列现在是 INTEGER(是 BLOB)并且保留了第 1 行。