假设我有一个简单的 Room 数据库:
@Database(entities = {User.class}, version = 1)
abstract class AppDatabase extends RoomDatabase {
public abstract Dao getDao();
}
现在,我要添加一个新实体: Pet
并将版本升级到 2:
@Database(entities = {User.class, Pet.class}, version = 2)
abstract class AppDatabase extends RoomDatabase {
public abstract Dao getDao();
}
当然,Room 抛出异常: java.lang.IllegalStateException: A migration from 1 to 2 is necessary.
假设,我没有更改 User
类(因此所有数据都是安全的),我必须提供只创建一个新表的迁移。因此,我正在研究 Room 生成的类,搜索生成的查询以创建我的新表,将其复制并粘贴到迁移中:
final Migration MIGRATION_1_2 =
new Migration(1, 2) {
@Override
public void migrate(@NonNull final SupportSQLiteDatabase database) {
database.execSQL("CREATE TABLE IF NOT EXISTS `Pet` (`name` TEXT NOT NULL, PRIMARY KEY(`name`))");
}
};
但是我发现手动操作不方便。有没有办法告诉 Room: 我没有触及任何现有表格,因此数据是安全的。请为我创建迁移?
原文由 Piotr Aleksander Chmielowski 发布,翻译遵循 CC BY-SA 4.0 许可协议
Room 没有 一个好的迁移系统,至少在
2.1.0-alpha03
之前没有。因此,在我们拥有更好的迁移系统之前,有一些解决方法可以在房间内轻松迁移。
由于没有
@Database(createNewTables = true)
或MigrationSystem.createTable(User::class)
这样的方法,应该有一个或另一个,唯一可能的方法是运行在你的
migrate
方法中。为了得到上面的 SQL 脚本,你有 4 种方法
1.自己写
基本上,您必须编写与 Room 生成的脚本相匹配的上述脚本。这种方式是可行的,不可行的。 (假设你有 50 个字段)
2.导出模式
如果您在 --- 注释中包含
exportSchema = true
@Database
注释,Room 将在项目文件夹的 /schemas 中生成数据库架构。用法是确保您已在应用程序模块的
build.grade
中包含以下行当您运行或构建项目时,您将获得一个 JSON 文件
2.json
,其中包含您的 Room 数据库中的所有查询。因此,您可以在 --- 方法中包含上面的
createSql
migrate
方法。3.从AppDatabase_Impl获取查询
如果您不想导出架构,您仍然可以通过运行或构建将生成
AppDatabase_Impl.java
文件的项目来获取查询。并在您可以拥有的指定文件中。在
createAllTables
方法中,将有所有实体的创建脚本。您可以获得它并将其包含在您的migrate
方法中。4.注解处理。
正如您可能猜到的那样,Room 会在编译时间内生成上述所有
schema
和AppDatabase_Impl
文件,并使用您添加的注释处理这意味着您也可以做同样的事情并制作自己的注释处理库,为您生成所有必要的创建查询。
这个想法是为
@Entity
和@Database
的房间注释制作一个注释处理库。以注解为@Entity
的类为例。这些是您必须遵循的步骤StringBuilder
并附加“如果不存在则创建表”class.simplename
或通过tableName
的字段@Entity
获取表名。将它添加到您的StringBuilder
@ColumnInfo
注释获取字段的名称、类型、可空性。对于每个字段,您必须将id INTEGER NOT NULL
添加到您的列样式StringBuilder
。@PrimaryKey
ForeignKey
和Indices
如果存在。然后,您可以将其用作
我为自己制作了这样一个库,您可以查看它,甚至可以在您的项目中使用它。请注意,我创建的库并不完整,它只是满足我创建表的要求。
用于更好迁移的 RoomExtension
使用 RoomExtension 的应用程序
希望它有用。
更新
在撰写此答案时,房间版本为
2.1.0-alpha03
当我向开发人员发送电子邮件时,我收到了回复不幸的是,我们仍然缺乏更好的迁移系统。