专栏名称: Android_开发者
目录
相关文章推荐
51好读  ›  专栏  ›  Android_开发者

Room 中的数据库关系

Android_开发者  · 掘金  · android  · 2020-03-06 03:14

正文

阅读 198

Room 中的数据库关系

设计一个关系型数据库很重要的一部分是将数据拆分成具有相关关系的数据表,然后将数据以符合这种关系的逻辑方式整合到一起。从 Room 2.2 的稳定版开始,我们可利用一个 @Relation 注解来支持表之间所有可能出现的关系: 一对一、一对多和多对多。

一对一关系

一对一关系

假设我们生活在一个每个人只能拥有一只狗,且每只狗只能有一个主人的 “悲惨世界” 中,这就是一对一关系。如果要以关系型数据库的方式来反应它的话,我们可以创建两张表: Dog 表和 Owner 表,其中 Dog 表通过 owner id 来引用 Owner 表中的数据,或者 Owner 表通过 dog id 来引用 Dog 表中的数据。


@Entity
data class Dog(
    @PrimaryKey val dogId: Long,
    val dogOwnerId: Long,
    val name: String,
    val cuteness: Int,
    val barkVolume: Int,
    val breed: String
)

@Entity
data class Owner(@PrimaryKey val ownerId: Long, val name: String)
复制代码

假设我们想在一个列表中展示所有的狗和它们的主人,我们需要创建一个 DogAndOwner 类:


data class DogAndOwner(
    val owner: Owner,
    val dog: Dog
)
复制代码

为了在 SQLite 中进行查询,我们需要 1) 运行两个查询: 一个获取所有的主人数据,一个获取所有的狗狗数据,2) 根据 owner id 来进行数据的关系映射。


SELECT * FROM Owner

SELECT * FROM Dog WHERE dogOwnerId IN (ownerId1, ownerId2, …)
复制代码

要在 Room 中获取一个 List ,我们不需要自己去实现上面说的查询和映射,只需要使用 @Relation 注解。

在我们的示例中,由于 Dog 有了 owner 的信息,我们给 dog 变量增加 @Relation 注解,指定父级 (这里对应 Owner) 上的 ownerId 列对应 dogOwnerId:

data class DogAndOwner(
    @Embedded val owner: Owner,
    @Relation(
         parentColumn = "ownerId",
         entityColumn = "dogOwnerId"
    )
    val dog: Dog
)
复制代码

现在我们的 Dao 类可被简化成:


@Transaction
@Query("SELECT * FROM Owner")

fun getDogsAndOwners(): List<DogAndOwner>
复制代码

注意: 由于 Room 会默默的帮我们运行两个查询请求,因此需要增加 @Transaction 注解来确保这个行为是原子性的。

Dao:

developer.android.google.cn/reference/a…

@Transaction:

developer.android.google.cn/reference/a…

一对多关系

一对多关系
再假设,一个主人可以养多只狗狗,现在上面的关系就变成了一对多关系。我们之前定义的数据库 schema 并不需要改变,仍然使用同样的表结构,因为在 “多” 这一方的表中已经有了关联键。

现在,要展示狗和主人的列表,我们需要创建一个新的类来进行建模:

data class OwnerWithDogs(
    val owner: Owner,
    val dogs: List<Dog>
)
复制代码

为了避免运行两个独立的查询,我们可以在 Dog 和 Owner 中定义一对多的关系,同样,还是在 List 前增加 @Relation 注解。


data class OwnerWithDogs(
     @Embedded val owner: Owner,
     @Relation(
          parentColumn = "ownerId",
          entityColumn = "dogOwnerId"
     )
     val dogs: List<Dog>
)
复制代码

现在,Dao 类又变成了这样:


@Transaction
@Query("SELECT * FROM Owner"






请到「今天看啥」查看全文


推荐文章
吃什么情报局  ·  ● 5款祛斑美白的食谱。
8 年前
爱健身  ·  100个男人只有一个能练出腹肌!
8 年前
数据分析与开发  ·  一览每周数据库技术干货和重要动态
7 年前