Room 在 SQLite 上提供了一个抽象层,以便在充分利用 SQLite 的强大功能的同时,能够流畅地访问数据库。
处理大量结构化数据的应用可极大地受益于在本地保留这些数据,最常见的方法就是缓存相关数据。这样,当设备无法访问网络时,用户仍可在离线状态下浏览相应内容。之后设备重新连接到网络后,用户发起的所有内容更改都会同步到服务器。
注意:要在应用中使用 Room,请在应用的 build.gradle
文件中声明 Room 依赖项。
声明依赖项
要添加 Room 的依赖项,您必须将 Google Maven 代码库添加到项目中。
在应用或模块的 build.gradle
文件中添加所需工件的依赖项:
1 | dependencies { |
配置编译器选项
Room 具有以下注解处理器选项:
room.schemaLocation
:配置并启用将数据库架构导出到给定目录中的 JSON 文件的功能。room.incremental
:启用 Gradle 增量注解处理器。room.expandProjection
:配置 Room 以重写查询,使其顶部星形投影在展开后仅包含 DAO 方法返回类型中定义的列。以下代码段举例说明了如何配置这些选项:
1
2
3
4
5
6
7
8
9
10
11
12
13
14android {
...
defaultConfig {
...
javaCompileOptions {
annotationProcessorOptions {
arguments = [
"room.schemaLocation":"$projectDir/schemas".toString(),
"room.incremental":"true",
"room.expandProjection":"true"]
}
}
}
}
组件
Room 包含 3 个主要组件:
Database:包含数据库持有者,并作为应用已保留的持久关系型数据的底层连接的主要接入点。
使用
@Database
注释的类应满足以下条件:- 是扩展
RoomDatabase
的抽象类 - 在注释中添加与数据库关联的实体列表
- 包含具有 0 个参数且返回使用
@Dao
注释的类的抽象方法
在运行时,您可以通过调用
Room.databaseBuilder()
或Room.inMemoryDatabaseBuilder()
获取Database
的实例。- 是扩展
Entity:表示数据库中的表。
- DAO:包含用于访问数据库的方法。
应用使用 Room 数据库来获取与该数据库关联的数据访问对象 (DAO)。然后,应用使用每个 DAO 从数据库中获取实体,然后再将对这些实体的所有更改保存回数据库中。最后,应用使用实体来获取和设置与数据库中的表列相对应的值。
Room 不同组件之间的关系如图 1 所示:
以下代码段包含具有一个实体和一个 DAO 的示例数据库配置。
User
1 |
|
UserDao
1 |
|
AppDatabase
1 | 1) (entities = {User.class}, version = |
创建上述文件后,您可以使用以下代码获取已创建的数据库的实例:
1 | AppDatabase db = Room.databaseBuilder(getApplicationContext(), |
注意:如果您的应用在单个进程中运行,则在实例化 AppDatabase
对象时应遵循单例设计模式。每个 RoomDatabase
实例的成本相当高,而您几乎不需要在单个进程中访问多个实例。
单例实现
1 | 1, exportSchema = false) (entities = {User.class}, version = |
以上实现了单例模式,可以在应用的Application通过UserRoomDatabase.getDatabase方法获取UserRoomDatabase的实例对象了。
当用户得到UserRoomDatabase对象之后,就可以通过上面的userDao()方法获取UserDao对象,然后就可以执行UserDao中的方法对数据库进行更删改查等操作了。
如果您的应用在多个进程中运行,请在数据库构建器调用中包含 enableMultiInstanceInvalidation()
。这样,如果您在每个进程中都有一个 AppDatabase
实例,就可以在一个进程中使共享数据库文件失效,并且这种失效会自动传播到其他进程中的 AppDatabase
实例。