กําหนดและค้นหาความสัมพันธ์แบบ 1:หลายรายการ

ความสัมพันธ์แบบหนึ่งต่อหลายรายการระหว่าง 2 เอนทิตีคือความสัมพันธ์ที่แต่ละอินสแตนซ์ของเอนทิตีหลักสอดคล้องกับอินสแตนซ์ของเอนทิตีย่อยตั้งแต่ 0 รายการขึ้นไป แต่แต่ละอินสแตนซ์ของเอนทิตีย่อยจะสอดคล้องกับอินสแตนซ์ของเอนทิตีหลักเพียง 1 รายการเท่านั้น

ในตัวอย่างแอปสตรีมมิงเพลง สมมติว่าผู้ใช้สามารถจัดระเบียบเพลงเป็นเพลย์ลิสต์ได้ ผู้ใช้แต่ละคนสร้างเพลย์ลิสต์ได้มากเท่าที่ต้องการ แต่มีผู้ใช้เพียง 1 คนเท่านั้นที่สร้างเพลย์ลิสต์แต่ละรายการ ดังนั้น จึงมีความสัมพันธ์แบบหนึ่งต่อหลายรายการระหว่างเอนทิตี User กับเอนทิตี Playlist

ทำตามขั้นตอนต่อไปนี้เพื่อกำหนดและค้นหาความสัมพันธ์แบบหนึ่งต่อหลายรายการในฐานข้อมูล

  1. **กำหนดความสัมพันธ์** : สร้างคลาสสำหรับทั้ง 2 เอนทิตี โดยเอนทิตีย่อยจะอ้างอิงคีย์หลักของเอนทิตีหลัก
  2. ค้นหาเอนทิตี: สร้างความสัมพันธ์ในคลาสข้อมูลใหม่ และใช้ฟังก์ชันเพื่อดึงข้อมูลที่เกี่ยวข้อง

กำหนดความสัมพันธ์

หากต้องการกำหนดความสัมพันธ์แบบหนึ่งต่อหลายรายการ ให้สร้างคลาสสำหรับแต่ละเอนทิตีก่อน เช่นเดียวกับความสัมพันธ์แบบหนึ่งต่อหนึ่ง เอนทิตีย่อยต้องมีตัวแปรที่อ้างอิงคีย์หลักของเอนทิตีหลัก

@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
)

ค้นหาเอนทิตี

หากต้องการค้นหารายการผู้ใช้และเพลย์ลิสต์ที่เกี่ยวข้อง คุณต้องสร้างความสัมพันธ์แบบหนึ่งต่อหลายรายการระหว่าง 2 เอนทิตีก่อน

หากต้องการสร้างความสัมพันธ์ ให้สร้างคลาสข้อมูลใหม่ แต่ละอินสแตนซ์ของคลาสนี้จะเก็บอินสแตนซ์ของเอนทิตีหลักและรายการอินสแตนซ์ของเอนทิตีย่อยที่เกี่ยวข้องทั้งหมด เพิ่มคำอธิบายประกอบ @Relation ลงในพร็อพเพอร์ตี้ที่แสดงรายการ เอนทิตีย่อย ตั้งค่า parentColumns เป็นชื่อคอลัมน์คีย์หลักของเอนทิตีหลัก และตั้งค่า entityColumns เป็นชื่อคอลัมน์ของเอนทิตีย่อย ที่อ้างอิงคีย์หลักของเอนทิตีหลัก

data class UserWithPlaylists(
    @Embedded val user: User,
    @Relation(
        parentColumns = ["userId"],
        entityColumns = ["userCreatorId"]
    )
    val playlists: List<Playlist>
)

สุดท้าย ให้เพิ่มฟังก์ชันลงในคลาสออบเจ็กต์การเข้าถึงข้อมูล (DAO) ที่แสดงอินสแตนซ์ทั้งหมดของคลาสข้อมูลที่จับคู่เอนทิตีหลักกับเอนทิตีย่อย เพิ่มคำอธิบายประกอบ @Transaction เพื่อให้ Room ดำเนินการทั้งหมด แบบอะตอมมิก คำอธิบายประกอบนี้จำเป็นเนื่องจากฟังก์ชันต้องให้ Room เรียกใช้การค้นหา 2 รายการ

@Transaction
@Query("SELECT * FROM User")
suspend fun getUsersWithPlaylists(): List<UserWithPlaylists>

คีย์ผสม

หากกำหนดความสัมพันธ์โดยใช้คีย์ผสม ให้ระบุคอลัมน์หลายรายการใน parentColumns และ entityColumns ลำดับคอลัมน์ใน parentColumns ต้องตรงกับลำดับคอลัมน์ใน entityColumns

@Entity(primaryKeys = ["firstName", "lastName"])
data class User(
    val firstName: String,
    val lastName: String,
    val age: Int
)

@Entity
data class Playlist(
    @PrimaryKey val playlistId: Long,
    val userFirstName: String,
    val userLastName: String,
    val playlistName: String
)

data class UserWithPlaylists(
    @Embedded val user: User,
    @Relation(
        parentColumns = ["firstName", "lastName"],
        entityColumns = ["userFirstName", "userLastName"]
    )
    val playlists: List<Playlist>
)