Xác định và truy vấn mối quan hệ một với nhiều
Sử dụng bộ sưu tập để sắp xếp ngăn nắp các trang
Lưu và phân loại nội dung dựa trên lựa chọn ưu tiên của bạn.
Mối quan hệ một với nhiều giữa hai thực thể là mối quan hệ trong đó mỗi bản sao của thực thể mẹ tương ứng với không hoặc nhiều bản sao của thực thể con, nhưng mỗi bản sao của thực thể con chỉ có thể tương ứng với đúng một bản sao của thực thể mẹ.
Trong ví dụ về ứng dụng phát nhạc trực tuyến, giả sử người dùng có thể sắp xếp các bài hát của họ vào danh sách phát. Mỗi người dùng có thể tạo số lượng danh sách phát tuỳ thích nhưng mỗi danh sách phát chỉ do duy nhất 1 người dùng tạo ra. Do đó, có một mối quan hệ một với nhiều giữa thực thể User
và thực thể Playlist
.
Hãy làm theo các bước sau để xác định và truy vấn mối quan hệ một với nhiều trong cơ sở dữ liệu:
- Xác định mối quan hệ: Tạo lớp cho cả hai thực thể, trong đó thực thể con tham chiếu đến khoá chính của thực thể mẹ.
- Truy vấn các thực thể: Mô hình hoá mối quan hệ trong một lớp dữ liệu mới và triển khai một phương thức để truy xuất dữ liệu liên quan.
Xác định mối quan hệ
Để xác định mối quan hệ một với nhiều, trước tiên, hãy tạo 1 lớp cho 2 thực thể.
Như trong mối quan hệ một với một, thực thể con phải bao gồm 1 biến tham chiếu đến khoá chính của thực thể mẹ.
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;
}
Truy vấn các thực thể
Để truy vấn danh sách người dùng và danh sách phát tương ứng, trước tiên, bạn phải mô hình hoá mối quan hệ một với nhiều giữa hai thực thể
Để thực hiện việc này, hãy tạo một lớp dữ liệu mới, trong đó mỗi bản sao sẽ chứa một bản sao của thực thể mẹ và một danh sách tất cả các bản sao của thực thể con tương ứng. Thêm chú thích @Relation
vào bản sao của thực thể con, trong đó parentColumn
được đặt làm tên cho cột khoá chính của thực thể mẹ và entityColumn
được đặt làm tên cho cột của thực thể con tham chiếu đến khoá chính của thực thể mẹ.
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;
}
Cuối cùng, thêm 1 phương thức vào lớp DAO sẽ trả về tất cả các bản sao của lớp dữ liệu có vai trò ghép nối thực thể mẹ và thực thể con. Phương thức này đòi hỏi Room chạy 2 truy vấn. Vì vậy, hãy thêm chú giải @Transaction
vào phương thức này để đảm bảo toàn bộ thao tác sẽ được thực hiện tỉ mỉ.
Kotlin
@Transaction
@Query("SELECT * FROM User")
fun getUsersWithPlaylists(): List<UserWithPlaylists>
Java
@Transaction
@Query("SELECT * FROM User")
public List<UserWithPlaylists> getUsersWithPlaylists();
Nội dung và mã mẫu trên trang này phải tuân thủ các giấy phép như mô tả trong phần Giấy phép nội dung. Java và OpenJDK là nhãn hiệu hoặc nhãn hiệu đã đăng ký của Oracle và/hoặc đơn vị liên kết của Oracle.
Cập nhật lần gần đây nhất: 2025-07-27 UTC.
[[["Dễ hiểu","easyToUnderstand","thumb-up"],["Giúp tôi giải quyết được vấn đề","solvedMyProblem","thumb-up"],["Khác","otherUp","thumb-up"]],[["Thiếu thông tin tôi cần","missingTheInformationINeed","thumb-down"],["Quá phức tạp/quá nhiều bước","tooComplicatedTooManySteps","thumb-down"],["Đã lỗi thời","outOfDate","thumb-down"],["Vấn đề về bản dịch","translationIssue","thumb-down"],["Vấn đề về mẫu/mã","samplesCodeIssue","thumb-down"],["Khác","otherDown","thumb-down"]],["Cập nhật lần gần đây nhất: 2025-07-27 UTC."],[],[],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();"]]