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

标签 android sqlite android-room

我想通过迁移自己显式在空数据库中创建所有数据库表。 我怎样才能做到这一点?

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

最佳答案

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

这并非不可靠,事实上恰恰相反。然而,应该理解的是,Room 是关于存储和检索对象的,而底层数据库管理器 SQLite 没有对象的概念,只有带有列的表。因此,Room 必须能够从一行或多行中的列创建对象(实体),因此必须满足规则。如果遇到的话Room还是比较靠谱的。

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

您可以通过对实体进行编码的方式来完成。然而,这些规则是有限制的,或者更正确地说,SQLite 的正确/正式使用可能是有限制的。因此,您可以控制架构,但它必须遵守 Room 的规则/限制

  • 列类型就是一个例子。

    • SQLite 对列类型有非常灵活的方法。事实上,任何东西都可以被接受为列类型。

    • 但是,Room 必须知道如何存储/提取对象(实体)。因此,Room 将列类型限制为 INTEGERTEXTREALBLOB(SQLite 支持的 4 种类型) 。 Room 不支持包罗万象的 NUMERIC 类型,也不支持 SQLite 通过 SQLite's rule for determining type affinity 将其他列类型转换为类型。 .

      • Room 永远不会接受定义为时间戳 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 注解的类,然后编译,因为您必须拥有实体。这样做将生成具有预期架构的代码。生成的代码位于生成的 java 中,可通过 Android Studio 中的 Android View 查看。它在类中是@Database注解的类名,后缀是_ImplcreateAllTables 方法中是 Room 在创建表时使用的创建表 SQL 语句。这是 Room 所期望的,并将遵守规则。

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

您可以在迁移中执行许多操作。如果引入新表,则需要创建新表,因为迁移会传递未更改的数据库。迁移的工作是更改数据库,从而根据 @Database 注释中定义的实体需要创建新表。

关于android - Room - 如何通过迁移首次显式创建所有表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70248919/

相关文章:

android - 使用 Room 递归调用 getDatabase

Android Studio Gradle 不使用传递依赖项

sql - 是否有一个命令结合了 SQL 中 UNION 和 JOIN 的功能?

android - 将 Eigen 库添加到 Android NDK

php - 将大型 JSON 数据从 php mysql 服务器加载到 java android 客户端

android - 如何在 android 上将 WHERE 子句添加到查询

rx-java - 房间 : LiveData or RxJava? 使用哪个

java - SQLiteConstraintException : How to map "no relationship" with a FOREIGN KEY in Room

Android:如何避免启动已经在堆栈中的 Activity ?

ANDROID:错误膨胀类 android.support.design.widget.AppBarLayout