Xác định và truy vấn mối quan hệ một với nhiều

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:

  1. 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ẹ.
  2. 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();