房确实不具备良好的迁移系统,至少直到2.1.0-alpha03
。
因此,在我们拥有更好的迁移系统之前,有一些变通办法可以在会议室中轻松进行迁移。
由于不存在这样的方法,@Database(createNewTables = true)
或者MigrationSystem.createTable(User::class)
,它应该有一个或另一个,唯一可能的方法是在运行
CREATE TABLE IF NOT EXISTS `User` (`id` INTEGER, PRIMARY KEY(`id`))
在您的migrate
方法中。
val MIGRATION_1_2 = object : Migration(1, 2){
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("CREATE TABLE IF NOT EXISTS `User` (`id` INTEGER, PRIMARY KEY(`id`))")
}
}
为了获得以上SQL脚本,您有四种方法
1.自己写
基本上,您必须编写与Room生成的脚本匹配的上述脚本。这种方式是可行的,是不可行的。(考虑您有50个字段)
2.导出模式
如果您exportSchema = true
在@Database
批注中加入,Room将在项目文件夹的/ schemas中生成数据库架构。用法是
@Database(entities = [User::class], version = 2, exportSchema = true)
abstract class AppDatabase : RoomDatabase {
//...
}
确保您已将以下行包括在内 build.grade
应用模块中
kapt {
arguments {
arg("room.schemaLocation", "$projectDir/schemas".toString())
}
}
在运行或构建项目时,您将获得一个JSON文件2.json
,其中包含Room数据库中的所有查询。
"formatVersion": 1,
"database": {
"version": 2,
"identityHash": "325bd539353db508c5248423a1c88c03",
"entities": [
{
"tableName": "User",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
因此,您可以包括以上内容 createSql
在您的migrate
方法中。
3.从AppDatabase_Impl获取查询
如果您不想导出架构,则仍然可以通过运行或构建将生成AppDatabase_Impl.java
文件的项目来获取查询。并在指定文件内。
@Override
public void createAllTables(SupportSQLiteDatabase _db) {
_db.execSQL("CREATE TABLE IF NOT EXISTS `User` (`id` INTEGER, PRIMARY KEY(`id`))");
在createAllTables
方法内,将存在所有实体的创建脚本。您可以获得并包含在您的内部migrate
方法中。
4.注释处理。
您可能会猜到,Room会在编译时间内并使用您添加的Annotation Processing 生成上述所有文件schema
和AppDatabase_Impl
文件。
kapt "androidx.room:room-compiler:$room_version"
这意味着您也可以这样做,并创建自己的注释处理库,该库将为您生成所有必要的创建查询。
这个想法是为@Entity
和的房间注释创建一个注释处理库@Database
。以带有注释的类@Entity
为例。这些是您必须遵循的步骤
- 新建
StringBuilder
并追加“如果不存在则创建表”
- 从
class.simplename
或通过的tableName
字段获取表名称@Entity
。将其添加到您的StringBuilder
- 然后为类的每个字段创建SQL列。通过字段本身或
@ColumnInfo
注释来获取字段的名称,类型和可空性。对于每个字段,您都必须在其中添加id INTEGER NOT NULL
列的样式StringBuilder
。
- 通过添加主键
@PrimaryKey
- 添加
ForeignKey
,Indices
如果存在。
- 完成后,将其转换为字符串并将其保存在您要使用的一些新类中。例如,将其保存如下
public final class UserSqlUtils {
public String createTable = "CREATE TABLE IF NOT EXISTS User (id INTEGER, PRIMARY KEY(id))";
}
然后,您可以将其用作
val MIGRATION_1_2 = object : Migration(1, 2){
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL(UserSqlUtils().createTable)
}
}
我为自己创建了一个这样的库,您可以检出它,甚至可以在您的项目中使用它。请注意,我制作的库并不完整,只满足我创建表的要求。
RoomExtension可实现更好的迁移
使用RoomExtension的应用程序
希望它有用。
更新
在撰写此答案时,会议室版本已定2.1.0-alpha03
,当我向开发人员发送电子邮件时,得到了答复
预计在 2.2.0
不幸的是,我们仍然缺乏更好的迁移系统。