定义和查询一对一关系

两个实体之间的一对一关系是指这样一种关系:父实体的每个实例恰好对应于子实体的 1 个实例,反之亦然。

例如,假设有一个音乐在线播放应用,用户在该应用中具有一个属于自己的歌曲库。每个用户只有一个库,而且每个库恰好对应于一个用户。因此,User 实体和 Library 实体之间是一对一的关系。

请按照以下步骤在数据库中定义和查询一对一关系:

  1. 定义关系:为这两个实体创建类,并确保其中一个类引用另一个类的主键。
  2. 查询实体:在新数据类中对关系进行建模,并创建一个函数来检索相关数据。

定义关系

如需定义一对一关系,请先为两个实体分别创建一个类。其中一个实体必须包含一个引用另一个实体主键的变量。

@Entity
data class User(
    @PrimaryKey val userId: Long,
    val name: String,
    val age: Int
)

@Entity
data class Library(
    @PrimaryKey val libraryId: Long,
    val userOwnerId: Long
)

查询实体

如需查询用户列表和对应的库,您必须先在两个实体之间建立一对一关系。

为了对这种关系进行建模,请创建一个新的数据类,其中每个实例都包含父实体的一个实例和相应的子实体。向子实体添加 @Relation 注释。将 parentColumns 设置为父实体主键列的名称,并将 entityColumns 设置为引用父实体主键的子实体列的名称。

data class UserAndLibrary(
    @Embedded val user: User,
    @Relation(
        parentColumns = ["userId"],
        entityColumns = ["userOwnerId"]
    )
    val library: Library
)

最后,向数据访问对象 (DAO) 类添加一个函数,用于返回将父实体与子实体配对的数据类的所有实例。添加 @Transaction 注释,以确保 Room 以原子方式执行整个操作,因为此函数需要 Room 运行两次查询。

@Transaction
@Query("SELECT * FROM User")
suspend fun getUsersAndLibraries(): List<UserAndLibrary>

复合键

如果您使用复合键定义关系,请在 parentColumnsentityColumns 中指定多个列。parentColumns 中的列顺序必须与 entityColumns 中的列顺序一致。

@Entity(primaryKeys = ["firstName", "lastName"])
data class User(
    val firstName: String,
    val lastName: String,
    val age: Int
)

@Entity
data class Library(
    @PrimaryKey val libraryId: Long,
    val userFirstName: String,
    val userLastName: String
)

data class UserAndLibrary(
    @Embedded val user: User,
    @Relation(
        parentColumns = ["firstName", "lastName"],
        entityColumns = ["userFirstName", "userLastName"]
    )
    val library: Library
)