房间没有一个好的迁移系统,至少在.2.1.0-alpha03
因此,在我们有更好的迁移系统之前,有一些解决方法可以在房间中轻松迁移。
由于没有 or 这样的方法,应该有一个或另一个,唯一可能的方法是运行@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脚本,您有4种方法
1. 自己写
基本上,您必须编写与Room生成的脚本相匹配的上述脚本。这种方式是可能的,但不可行。(假设您有 50 个字段)
2. 导出架构
如果包含在批注中,Room 将在项目文件夹的 /schemas 中生成数据库架构。用法是exportSchema = true
@Database
@Database(entities = [User::class], version = 2, exportSchema = true)
abstract class AppDatabase : RoomDatabase {
//...
}
确保在应用模块中包含以下行build.grade
kapt {
arguments {
arg("room.schemaLocation", "$projectDir/schemas".toString())
}
}
当您运行或构建项目时,您将获得一个 JSON 文件 ,其中包含 Room 数据库中的所有查询。2.json
"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 会在编译时间内生成上述所有文件,并带有注释处理功能,您可以使用这些注释处理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 的应用程序
希望它有用。
更新
在撰写此答案时,房间版本是,当我向开发人员发送电子邮件时,我得到了回复2.1.0-alpha03
预计在以下方面将有更好的迁移系统2.2.0
不幸的是,我们仍然缺乏更好的迁移系统。