定义和查询一对一关系

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

例如,假设有一个音乐在线播放应用,用户在该应用中具有一个属于自己的歌曲库。每个用户只有一个库,而且每个库恰好对应于一个用户。因此,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();