我在我的Android应用程序中使用Room数据库,它提供了一个包含Car
个元素的表格,如下所示:
@Entity(tableName = "Cars")
data class Car(
@PrimaryKey(autoGenerate = true) @ColumnInfo(name = "Id") val id: Int? = null,
@ColumnInfo(name = "Manufacture") var manufacture: String? = null,
@ColumnInfo(name = "Model") var model: String? = null,
@ColumnInfo(name = "Date_created") val dateCreated: String? = null,
@ColumnInfo(name = "Date_modified") var dateModified: String? = null,
@ColumnInfo(name = "Color") var color: String? = null,
@ColumnInfo(name = "Tags") var tags: String? = null
)
现在,我需要对该表执行一些更改,并按如下方式升级它: 现在,我需要在表中应用一些更改:
@Entity(tableName = "Cars")
data class Car(
@PrimaryKey(autoGenerate = true) @ColumnInfo(name = "Id") var id: Long = 0,
@ColumnInfo(name = "Manufacture") var manufacture: String = "",
@ColumnInfo(name = "Model") var model: String = "",
@ColumnInfo(name = "Labels") var labels: List<String> = listOf(),
@ColumnInfo(name = "Color") var color: String? = null,
@ColumnInfo(name = "Timestamp") var timestamp: Long = 0L,
@ColumnInfo(name = "Type") var type: Type = Type.Sedan,
@ColumnInfo(name = "Folder") var folder: Folder = Folder.Used
)
此次升级将对现有表格进行以下更改:
- 第
Id
栏:val id: Int? = null
改为val id: Long = 0
. - 第
Manufacture
栏:var manufacture: String? = null
改为var manufacture: String = ""
. - 第
Date_created
栏:var dateCreated: String? = null
栏已删除. - 列
Date_modified
重命名为Timestamp
,其数据类型也从可为空的String
变为不可为空的Long
.是否可以在迁移过程中将字符串转换为Long?这些字符串值是转换为字符串timestampe.toString()
的时间戳. - 数据类型
var tags: String? = null
的列Tags
(由逗号分隔的一个字符串中的标签:例如"Gas,Diesel,Oil"
)改变为列表var labels: List<String> = listOf()
的标签.是否可以在迁移时将标签串转换为列表? - 列
Type
和Folder
是数据类型enum
的新列.
我对一些数据类型提出了问题,这些数据类型必须更改为另一种数据类型,因为我找不到任何有关此主题的信息.尽管如此,我还是基于Migrate your Room database和Understanding migrations with Room做了一个小的变通方法,但不确定语法和数据类型转换:
@Database(entities = [Car::class], version = 2, exportSchema = false)
abstract class CarsDatabase : RoomDatabase() {
abstract val carDao: CarDao
companion object {
@Volatile
private var INSTANCE: CarsDatabase? = null
private val migration = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
database.apply {
execSQL(
"CREATE TABLE cars_tmp (" +
"Id INTEGER, " +
"Manufacture TEXT, " +
"Model TEXT, " +
"Timestamp LONG, " + // Not sure about syntax for Long
"Labels LIST," + // Not sure about syntax for List<String>
"PRIMARY KEY(Id)" +
")"
)
execSQL("INSERT INTO cars_tmp (" +
"Id, Manufacture, Model, Timestamp, Labels, Color) SELECT " +
"Id, Manufacture, Model, Date_modified, Tags, Color" + // String of "Date_modified" being converted to Long of "Timestamp" and String of "Tags" being converted to List<String>
"FROM Cars"
)
execSQL("DROP TABLE Car")
execSQL("ALTER TABLE cars_tmp RENAME TO Car")
execSQL("ALTER TABLE Car ADD COLUMN Type TEXT")
execSQL("ALTER TABLE Car ADD COLUMN Folder TEXT")
}
}
}
fun getInstance(context: Context): CarsDatabase = INSTANCE ?: synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
CarsDatabase::class.java,
"Cars.db"
)
.addMigrations(migration)
.build()
INSTANCE = instance
return instance
}
}
}
我不指望有人会做我的工作,但我至少我真的需要一些关于我的问题的答案,以便很好地完成migrations.我对SQL语法非常陌生,因此,我的迁移代码是错误的.
如有任何帮助,敬请惠顾.
编辑: 答案可以在这里找到:How to correctly get the path of Room database on os versions >= 26 sdk?