…
productDao.insertProduct(productEntity);
每个 entity 都代表了一张表,其中的字段代表表中的一列。注解处理器会自动生成 AppDatabase
和 ProductDao
对应的实现类 AppDatabase_Impl
和 ProductDao_Impl
。可以通过调用Room.databaseBuilder()
或 Room.inMemoryDatabaseBuilder()
在运行时获取Database
实例,但要注意,实例化 RoomDatabase
是相当昂贵的,最好按照单例模式只创建一个Database
实例。
定义 Entity
为了让 Room 可以访问 entity,entity 中的字段必须是 public 的,或者提供了getter/setter方法。默认情况下,Room 会将 entity 中的每个字段作为数据库表中一列,如果你不想持久化某个字段,可以使用 @Ignore
注解。默认数据库表名为 entity 类名,你可以通过 @Entity
注解的 tableName
属性 更改,默认列名是字段名,你可以通过 @ColumnInfo
注解更改。
主键
每个 entity 必须至少有一个字段作为主键(primary key),即使该 entity 只有一个字段。使用 @PrimaryKey
注解来指定主键,如果你希望 SQLite 帮你自动生成这个唯一主键,需要将 @PrimaryKey
的 autoGenerate
属性设置成 true
,不过需要改列是 INTEGER
类型的。如果字段类型是 long
或 int
,Insert
方法会将 0 作为缺省值,如果字段类型是 Integer
或 Long
类型,Insert
方法会将 null 作为缺省值。
如果 entity 的主键是复合主键(composite primary key),你就需要使用 @Entity
注解的 primaryKeys
属性定义这个约束,如:
@Entity(primaryKeys = {“firstName”, “lastName”})
class User {
public String firstName;
public String lastName;
public String avatar;
}
索引
有些时候,我们需要添加索引以加快查询速度,可以使用 @ Entity
注解的 indices
属性创建索引,如果某个字段或字段组是唯一的,可以将 @Index
注解的 unique
属性设置为 true
来强制这个唯一性,如:
@Entity(indices = {@Index(value = {“first_name”, “last_name”},
unique = true)})
class User {
@PrimaryKey
public int id;
@ColumnInfo(name = “first_name”)
public String firstName;
@ColumnInfo(name = “last_name”)
public String lastName;
@Ignore
Bitmap picture;
}
关系
SQLite 是关系型数据库,很多时候我们需要指定对象间的关系。即使大多数 ORM 库允许实体类对象间相互引用,但 Room 明确禁止这样做。因为级联查询不能发生在 UI 线程,UI 线程只有 16 ms 时间计算和绘制布局,所以即使一个查询只花费 5 ms,你的应用仍可能因此绘制超