ความสัมพันธ์แบบหนึ่งต่อหลายรายการระหว่าง 2 เอนทิตีคือความสัมพันธ์ที่แต่ละอินสแตนซ์ของเอนทิตีหลักสอดคล้องกับอินสแตนซ์ของเอนทิตีย่อยตั้งแต่ 0 รายการขึ้นไป แต่แต่ละอินสแตนซ์ของเอนทิตีย่อยจะสอดคล้องกับอินสแตนซ์ของเอนทิตีหลักเพียง 1 รายการเท่านั้น
ในตัวอย่างแอปสตรีมมิงเพลง สมมติว่าผู้ใช้สามารถจัดระเบียบเพลงเป็นเพลย์ลิสต์ได้ ผู้ใช้แต่ละคนสร้างเพลย์ลิสต์ได้มากเท่าที่ต้องการ แต่มีผู้ใช้เพียง 1 คนเท่านั้นที่สร้างเพลย์ลิสต์แต่ละรายการ ดังนั้น จึงมีความสัมพันธ์แบบหนึ่งต่อหลายรายการระหว่างเอนทิตี User กับเอนทิตี Playlist
ทำตามขั้นตอนต่อไปนี้เพื่อกำหนดและค้นหาความสัมพันธ์แบบหนึ่งต่อหลายรายการในฐานข้อมูล
- **กำหนดความสัมพันธ์** : สร้างคลาสสำหรับทั้ง 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> )