定义和查询一对多关系
使用集合让一切井井有条
根据您的偏好保存内容并对其进行分类。
两个实体之间的一对多关系是指这样一种关系:父实体的每个实例对应于子实体的零个或多个实例,但子实体的每个实例只能恰好对应于父实体的一个实例。
在音乐在线播放应用示例中,假设用户可以将其歌曲整理到播放列表中。每个用户可以创建任意数量的播放列表,但每个播放列表只能由一个用户创建。因此,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();
本页面上的内容和代码示例受内容许可部分所述许可的限制。Java 和 OpenJDK 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2025-07-27。
[null,null,["最后更新时间 (UTC):2025-07-27。"],[],[],null,["# Define and query one-to-many relationships\n\nA *one-to-many relationship* between two entities is a relationship where each\ninstance of the parent entity corresponds to zero or more instances of the child\nentity, but each instance of the child entity can only correspond to exactly one\ninstance of the parent entity.\n\nIn the music streaming app example, suppose the user has the ability to organize\ntheir songs into playlists. Each user can create as many playlists as they want,\nbut exactly one user creates each playlist. Therefore, there is a one-to-many\nrelationship between the `User` entity and the `Playlist` entity.\n\nFollow these steps to define and query one-to-many relationships in your\ndatabase:\n\n1. **[Define the relationship](#define)**: Create classes for both entities, with the child entity referencing the parent's primary key.\n2. **[Query the entities](#query)**: Model the relationship in a new data class and implement a method to retrieve the related data.\n\nDefine the relationship\n-----------------------\n\nTo define a one-to-many relationship, first create a class for the two entities.\nAs in a one-to-one relationship, the child entity must include a variable that\nis a reference to the primary key of the parent entity. \n\n### Kotlin\n\n @Entity\n data class User(\n @PrimaryKey val userId: Long,\n val name: String,\n val age: Int\n )\n\n @Entity\n data class Playlist(\n @PrimaryKey val playlistId: Long,\n val userCreatorId: Long,\n val playlistName: String\n )\n\n### Java\n\n @Entity\n public class User {\n @PrimaryKey public long userId;\n public String name;\n public int age;\n }\n\n @Entity\n public class Playlist {\n @PrimaryKey public long playlistId;\n public long userCreatorId;\n public String playlistName;\n }\n\nQuery the entities\n------------------\n\nTo query the list of users and corresponding playlists, you must first model the\none-to-many relationship between the two entities\n\nTo do this, create a new data class where each instance holds an instance of the\nparent entity and a list of all corresponding child entity instances. Add the\n[`@Relation`](/reference/kotlin/androidx/room/Relation) annotation to the instance of the child entity, with\n[`parentColumn`](/reference/kotlin/androidx/room/Relation#parentColumn()) set to the name of the primary key column of the parent\nentity and [`entityColumn`](/reference/kotlin/androidx/room/Relation#entityColumn()) set to the name of the column of the child entity\nthat references the parent entity's primary key. \n\n### Kotlin\n\n data class UserWithPlaylists(\n @Embedded val user: User,\n @Relation(\n parentColumn = \"userId\",\n entityColumn = \"userCreatorId\"\n )\n val playlists: List\u003cPlaylist\u003e\n )\n\n### Java\n\n public class UserWithPlaylists {\n @Embedded public User user;\n @Relation(\n parentColumn = \"userId\",\n entityColumn = \"userCreatorId\"\n )\n public List\u003cPlaylist\u003e playlists;\n }\n\nFinally, add a method to the DAO class that returns all instances of the data\nclass that pairs the parent entity and the child entity. This method requires\nRoom to run two queries, so add the [`@Transaction`](/reference/kotlin/androidx/room/Transaction) annotation to this\nmethod so that the whole operation is performed atomically. \n\n### Kotlin\n\n @Transaction\n @Query(\"SELECT * FROM User\")\n fun getUsersWithPlaylists(): List\u003cUserWithPlaylists\u003e\n\n### Java\n\n @Transaction\n @Query(\"SELECT * FROM User\")\n public List\u003cUserWithPlaylists\u003e getUsersWithPlaylists();"]]