两个实体之间的一对一关系是指这样一种关系:父实体的每个实例恰好对应于子实体的 1 个实例,反之亦然。
例如,假设有一个音乐在线播放应用,用户在该应用中具有一个属于自己的歌曲库。每个用户只有一个库,而且每个库恰好对应于一个用户。因此,User
实体和 Library
实体之间是一对一的关系。
如需在数据库中定义和查询一对一关系,请按以下步骤操作:
定义关系
如需定义一对一关系,请先为两个实体分别创建一个类。其中一个实体必须包含一个变量,且该变量是对另一个实体的主键的引用。
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();