定義及查詢一對多關係
透過集合功能整理內容
你可以依據偏好儲存及分類內容。
兩個實體之間的「一對多關係」是指父系實體的每個例項分別對應到子實體的零個或更多例項,但子實體的每個例項只能確切對應到一個父系實體的例項。
在音樂串流應用程式範例中,假設使用者能夠將歌曲整理成多個播放清單。每位使用者可以建立任意數量的播放清單,但每個播放清單僅由一位使用者建立。因此,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 和/或其關係企業的商標或註冊商標。
上次更新時間:2025-07-27 (世界標準時間)。
[null,null,["上次更新時間: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();"]]