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