定义和查询一对多关系

两个实体之间的一对多关系是指,父实体的每个实例可以对应零个或多个子实体实例,但子实体的每个实例只能对应一个父实体实例。

在音乐流媒体应用示例中,假设用户可以将他们的歌曲整理到播放列表中。每个用户可以创建任意数量的播放列表,但每个播放列表都由且仅由一个用户创建。因此,User 实体和 Playlist 实体之间存在一对多关系。

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

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

定义关系

要定义一对多关系,首先为这两个实体创建一个类。与一对一关系一样,子实体必须包含一个变量,该变量是父实体主键的引用。

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();