定义和查询一对一关系

两个实体之间的一对一关系是指父实体的每个实例都精确对应子实体的一个实例,反之亦然。

例如,考虑一个音乐流媒体应用,用户拥有歌曲库。每个用户只有一个库,每个库精确对应一个用户。因此,User 实体和 Library 实体之间存在一对一关系。

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

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

定义关系

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

Kotlin

@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
)

Java

@Entity
public class User {
    @PrimaryKey public long userId;
    public String name;
    public int age;
}

@Entity
public class Library {
    @PrimaryKey public long libraryId;
    public long userOwnerId;
}

查询实体

要查询用户及其对应库的列表,必须首先在两个实体之间建模一对一关系。

为此,创建一个新的数据类,其中每个实例都包含父实体的一个实例和子实体的对应实例。将 @Relation 注解添加到子实体的实例,其中 parentColumn 设置为父实体的主键列名,entityColumn 设置为子实体中引用父实体主键的列名。

Kotlin

data class UserAndLibrary(
    @Embedded val user: User,
    @Relation(
         parentColumn = "userId",
         entityColumn = "userOwnerId"
    )
    val library: Library
)

Java

public class UserAndLibrary {
    @Embedded public User user;
    @Relation(
         parentColumn = "userId",
         entityColumn = "userOwnerId"
    )
    public Library library;
}

最后,向 DAO 类添加一个方法,该方法返回配对父实体和子实体的数据类的所有实例。此方法要求 Room 运行两次查询。因此,应为此方法添加 @Transaction 注解。这可确保整个操作以原子方式运行。

Kotlin

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

Java

@Transaction
@Query("SELECT * FROM User")
public List<UserAndLibrary> getUsersAndLibraries();