与直接使用 SQLite API 相比,Room 持久性库具有诸多优势:
- 针对 SQL 查询的编译时验证
- 可最大限度减少重复和容易出错的样板代码的方便注解
- 简化了数据库迁移路径
如果您的应用具有非 Room SQLite 实现,请阅读本页面,了解如何迁移到 Room。如果 Room 是您应用中的第一个 SQLite 实现,请参阅使用 Room 将数据保存到本地数据库,了解基本用法。
迁移步骤
执行以下步骤,将您的 SQLite 实现迁移到 Room。如果您的 SQLite 实现使用大型数据库或复杂查询,您可能希望逐步迁移到 Room。如需详细了解增量迁移策略,请参阅增量迁移。
更新依赖项
如需在应用中使用 Room,您必须在应用的 build.gradle 文件中添加适当的依赖项。如需详细了解 Room 依赖项,请参阅设置。
将模型类更新为数据实体
Room 使用数据实体来表示数据库中的表。每个实体类代表一个表,并且具有表示该表中各个列的属性。请按照以下步骤将您的现有模型类更新为 Room 实体:
- 使用
@Entity为类声明添加注解,以表明它是 Room 实体。您可以选择使用tableName属性,以指明生成的表的名称应该与类名称不同。 - 使用
@PrimaryKey为主键属性添加注解。 - 如果结果表中的任何列的名称都应该与相应属性的名称不同,请为该属性添加
@ColumnInfo注解并将name属性设置为正确的列名。 - 如果类包含您不想在数据库中保留的属性,请使用
@Ignore为这些属性添加注解,以指明 Room 不应为它们创建列。 - 如果该类具有多个构造函数,请使用
@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 ...")