Room 持久性库相对于直接使用 SQLite API 提供了许多优势:
- 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 应该使用哪个构造函数。
Kotlin
@Entity(tableName = "users") data class User( @PrimaryKey @ColumnInfo(name = "userid") val mId: String, @ColumnInfo(name = "username") val mUserName: String?, @ColumnInfo(name = "last_update") val mDate: Date?, )
Java
@Entity(tableName = "users") public class User { @PrimaryKey @ColumnInfo(name = "userid") private String mId; @ColumnInfo(name = "username") private String mUserName; @ColumnInfo(name = "last_update") private Date mDate; @Ignore public User(String userName) { mId = UUID.randomUUID().toString(); mUserName = userName; mDate = new Date(System.currentTimeMillis()); } public User(String id, String userName, Date date) { this.mId = id; this.mUserName = userName; this.mDate = date; } }
创建 DAO
Room 使用数据访问对象 (DAO) 来定义访问数据库的方法。遵循使用 Room DAO 访问数据中的指导,将你现有的查询方法替换为 DAO。
创建数据库类
Room 的实现使用数据库类来管理数据库实例。你的数据库类应扩展 RoomDatabase
并引用你定义的所有实体和 DAO。
Kotlin
@Database(entities = [User::class], version = 2) @TypeConverters(DateConverter::class) abstract class UsersDatabase : RoomDatabase() { abstract fun userDao(): UserDao }
Java
@Database(entities = {User.class}, version = 2) @TypeConverters(DateConverter.class) public abstract class UsersDatabase extends RoomDatabase { public abstract UserDao userDao(); }
定义迁移路径
由于数据库版本号正在改变,你必须定义一个 Migration
对象来指示迁移路径,以便 Room 保留数据库中的现有数据。只要数据库 schema 没有改变,这可以是一个空的实现。
Kotlin
val MIGRATION_1_2 = object : Migration(1, 2) { override fun migrate(database: SupportSQLiteDatabase) { // Empty implementation, because the schema isn't changing. } }
Java
static final Migration MIGRATION_1_2 = new Migration(1, 2) { @Override public void migrate(SupportSQLiteDatabase database) { // Empty implementation, because the schema isn't changing. } };
要了解更多关于 Room 数据库迁移路径的信息,请参阅迁移数据库。
更新数据库实例化
定义数据库类和迁移路径后,可以使用 Room.databaseBuilder
创建一个应用了迁移路径的数据库实例。
Kotlin
val db = Room.databaseBuilder( applicationContext, AppDatabase::class.java, "database-name" ) .addMigrations(MIGRATION_1_2).build()
Java
db = Room.databaseBuilder( context.getApplicationContext(), UsersDatabase.class, "database-name" ) .addMigrations(MIGRATION_1_2).build();
测试你的实现
确保测试你的新的 Room 实现
增量迁移
如果你的应用使用大型、复杂的数据库,可能无法一次性将应用完全迁移到 Room。作为替代方案,你可以选择先实现数据实体和 Room 数据库,稍后再将你的查询方法迁移到 DAO 中。你可以通过将自定义的 数据库帮助类 替换为从 RoomDatabase.getOpenHelper()
获取的 SupportSQLiteOpenHelper
对象来实现这一点。
其他资源
如需详细了解从 SQLite 迁移到 Room 的信息,请参阅以下其他资源: