从 SQLite 迁移到 Room

与直接使用 SQLite API 相比,Room 持久性库具有诸多优势:

  • 针对 SQL 查询的编译时验证
  • 可最大限度减少重复和容易出错的样板代码的方便注解
  • 简化了数据库迁移路径

如果您的应用具有非 Room SQLite 实现,请阅读本页面,了解如何迁移到 Room。如果 Room 是您应用中的第一个 SQLite 实现,请参阅使用 Room 将数据保存到本地数据库,了解基本用法。

迁移步骤

执行以下步骤,将您的 SQLite 实现迁移到 Room。如果您的 SQLite 实现使用大型数据库或复杂查询,您可能希望逐步迁移到 Room。如需详细了解增量迁移策略,请参阅增量迁移

更新依赖项

如需在应用中使用 Room,您必须在应用的 build.gradle 文件中添加适当的依赖项。如需详细了解 Room 依赖项,请参阅设置

将模型类更新为数据实体

Room 使用数据实体来表示数据库中的表。每个实体类代表一个表,并且具有表示该表中各个列的属性。请按照以下步骤将您的现有模型类更新为 Room 实体:

  1. 使用 @Entity 为类声明添加注解,以表明它是 Room 实体。您可以选择使用 tableName 属性,以指明生成的表的名称应该与类名称不同。
  2. 使用 @PrimaryKey 为主键属性添加注解。
  3. 如果结果表中的任何列的名称都应该与相应属性的名称不同,请为该属性添加 @ColumnInfo 注解并将 name 属性设置为正确的列名。
  4. 如果类包含您不想在数据库中保留的属性,请使用 @Ignore 为这些属性添加注解,以指明 Room 不应为它们创建列。
  5. 如果该类具有多个构造函数,请使用 @Ignore 为所有其他构造函数添加注解,指明 Room 应使用哪个构造函数。

@Entity(tableName = "users")
data class User(
    @PrimaryKey @ColumnInfo(name = "userid") val id: String,
    @ColumnInfo(name = "username") val userName: String?,
    @ColumnInfo(name = "last_update") val date: Date?,
)

创建 DAO

Room 使用数据访问对象 (DAO) 来定义访问数据库的函数。按照使用 Room DAO 访问数据中的指南,将现有查询函数替换为 DAO。

创建数据库类

Room 实现使用数据库类来管理数据库的实例。您的数据库类应该扩展 RoomDatabase 并引用您已定义的所有实体和 DAO。

@Database(entities = [User::class], version = 2)
@ColumnTypeConverters(DateConverter::class)
abstract class UsersDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao
}

定义迁移路径

由于数据库版本号发生了变化,因此您必须定义 Migration 对象以保留现有数据库数据。如果数据库架构没有变化,则此迁移可以为空。

val MIGRATION_1_2 = object : Migration(1, 2) {
    override suspend fun migrate(connection: SQLiteConnection) {
        // Empty implementation, because the schema isn't changing.
    }
}

如需详细了解 Room 中的数据库迁移路径,请参阅迁移数据库

更新数据库实例化

定义数据库类和迁移路径后,您可以使用 Room.databaseBuilder 创建一个应用迁移路径的数据库实例:

val db =
    Room.databaseBuilder<UsersDatabase>(applicationContext, "database-name")
        .addMigrations(MIGRATION_1_2)
        .build()

测试实现效果

请务必测试新的 Room 实现:

增量迁移

如果应用使用复杂的大型数据库,则可能无法一次性将应用迁移到 Room。相反,您可以先选择实现数据实体和 Room 数据库,然后在以后将查询函数迁移到 DAO。

如需实现增量迁移,请使用 androidx.room3:room3-sqlite-wrapper 制品的 roomDatabase.getSupportWrapper 扩展函数获取 SupportSQLiteDatabase 兼容性封装容器。借助此封装容器,您可以使用 Android SQLite API 对 Room 管理的数据库执行直接的 Android 风格 SQL 查询:

// Get SupportSQLiteDatabase wrapper
val legacyDb = roomDatabase.getSupportWrapper()
legacyDb.execSQL("INSERT INTO users ...")