Room - 如何通过迁移第一次显式创建所有表?

Room - How to explicitly create all tables first time via migration?

我想明确地自己通过迁移在一个空数据库中创建所有数据库表。 我该怎么做?

Room 始终使用实体 类 自行创建初始表。这是一种不可靠的方法。我无法控制架构,不得不依赖 Room。

Room always creates initial tables itself using entity classes. This is an unreliable approach.

其实不靠谱,恰恰相反。然而,应该理解的是,当底层数据库管理器 SQLite 没有对象的概念,只有 tables 与列时,Room 是关于存储和检索对象的。因此,Room 必须能够从一行或多行中的列创建对象(实体),因此必须满足规则。遇到的话Room还是挺靠谱的。

I can't control schema and have to rely on Room.

您可以通过对实体进行编码来实现。然而,规则有限制 或者更正确的是 proper/formal 使用 SQLite。因此您可以控制模式,但它 必须遵守 Room 的 rules/limitations.

  • 一个例子是列类型。

    • SQLite 对列类型有非常灵活的方法。因为几乎任何东西都可以被接受为列类型。

    • 房间不过,必须知道如何store/extract对象(实体)。因此 Room 将列类型限制为 INTEGERTEXTREALBLOB(SQLite 支持的 4 种类型)。 Room 不支持包罗万象的 NUMERIC 类型,也不支持 SQLite 通过 SQLite's rule for determining type affinity.

      将其他列类型转换为类型
      • Room 永远不会接受定义为 timestamp DATE 的列作为示例,因为 DATE 不是 INTEGER、TEXT、REAL 或 BLOB 之一(在 SQLite DATE 解析为类型关联NUMERIC,包罗万象)。

I want to explicitly create all DB tables in an empty database myself via migration. How can I do this?

简而言之,执行以下操作之一:

  1. 定义架构时遵循 Room 的规则,
  2. 聪明一点,让 Room 来完成工作(如下所述),或者
  3. 使用原生 SQLite 而不是 Room。
  • 聪明的方法,因为你必须有实体,是创建实体和用@Database 注释的 class 然后编译。这样做将生成具有 expected 模式的代码。生成的代码位于生成的 java 中,可通过 Android Studio 中的 Android 视图查看。它在 class 中,这是 class 的名称,用 @Database 注释,后缀为 _Impl。在 createAllTables 方法中是创建 table SQL 语句,当 Room 创建 table 时,Room 使用该语句。这就是 Room 所期待的,也会遵守规则的。

  • 然后您可以使用 Room 创建的 SQL 作为创建或修改 table 的基础。

您可以在迁移中做很多事情。如果引入了新的 tables,那么创建新的 tables 将是一项要求,因为迁移是通过未更改的数据库进行的。迁移的工作是更改数据库,因此如果需要根据 @Database 注释中定义的实体创建新的 tables。