两个实体之间的一对多关系是指,父实体的每个实例可以对应零个或多个子实体实例,但子实体的每个实例只能对应一个父实体实例。
在音乐流媒体应用示例中,假设用户可以将他们的歌曲整理到播放列表中。每个用户可以创建任意数量的播放列表,但每个播放列表都由且仅由一个用户创建。因此,User
实体和 Playlist
实体之间存在一对多关系。
按照以下步骤在数据库中定义和查询一对多关系
定义关系
要定义一对多关系,首先为这两个实体创建一个类。与一对一关系一样,子实体必须包含一个变量,该变量是父实体主键的引用。
Kotlin
@Entity
data class User(
@PrimaryKey val userId: Long,
val name: String,
val age: Int
)
@Entity
data class Playlist(
@PrimaryKey val playlistId: Long,
val userCreatorId: Long,
val playlistName: String
)
Java
@Entity
public class User {
@PrimaryKey public long userId;
public String name;
public int age;
}
@Entity
public class Playlist {
@PrimaryKey public long playlistId;
public long userCreatorId;
public String playlistName;
}
查询实体
要查询用户列表及其对应的播放列表,您必须首先对两个实体之间的一对多关系进行建模
为此,创建一个新的数据类,其中每个实例都包含一个父实体实例和所有对应子实体实例的列表。为子实体实例添加 @Relation
注解,将 parentColumn
设置为父实体主键列的名称,将 entityColumn
设置为引用父实体主键的子实体列的名称。
Kotlin
data class UserWithPlaylists(
@Embedded val user: User,
@Relation(
parentColumn = "userId",
entityColumn = "userCreatorId"
)
val playlists: List<Playlist>
)
Java
public class UserWithPlaylists {
@Embedded public User user;
@Relation(
parentColumn = "userId",
entityColumn = "userCreatorId"
)
public List<Playlist> playlists;
}
最后,向 DAO 类添加一个方法,该方法返回配对父实体和子实体的所有数据类实例。此方法需要 Room 运行两次查询,因此请向该方法添加 @Transaction
注解,以使整个操作原子性执行。
Kotlin
@Transaction
@Query("SELECT * FROM User")
fun getUsersWithPlaylists(): List<UserWithPlaylists>
Java
@Transaction
@Query("SELECT * FROM User")
public List<UserWithPlaylists> getUsersWithPlaylists();