บางครั้งคุณอาจต้องค้นหาชุดตาราง 3 รายการขึ้นไปที่เกี่ยวข้องกับตารางอื่นๆ ในกรณีดังกล่าว ให้กำหนด ความสัมพันธ์แบบซ้อนระหว่างตาราง
สมมติว่าในตัวอย่างแอปสตรีมมิงเพลง คุณต้องการค้นหาผู้ใช้ทั้งหมด เพลย์ลิสต์ทั้งหมดของผู้ใช้แต่ละราย และเพลงทั้งหมดในเพลย์ลิสต์แต่ละรายการของผู้ใช้แต่ละราย ผู้ใช้มีความสัมพันธ์แบบหนึ่งต่อหลายกับเพลย์ลิสต์ และ เพลย์ลิสต์มีความสัมพันธ์แบบหลายต่อหลายกับเพลง ตัวอย่างโค้ดต่อไปนี้แสดงคลาสที่แสดงเอนทิตีเหล่านี้ รวมถึงตารางการอ้างอิงโยงสำหรับความสัมพันธ์แบบหลายต่อหลายระหว่างเพลย์ลิสต์กับเพลง
@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 ) @Entity data class Song( @PrimaryKey val songId: Long, val songName: String, val artist: String ) @Entity(primaryKeys = ["playlistId", "songId"], indices = [Index("playlistId", "songId")]) data class PlaylistSongCrossRef( val playlistId: Long, val songId: Long )
ขั้นแรก ให้สร้างโมเดลความสัมพันธ์ระหว่างตาราง 2 รายการในชุดตามที่คุณ
ทำตามปกติ โดยใช้คลาสข้อมูลและคำอธิบายประกอบ @Relation ตัวอย่างต่อไปนี้แสดงคลาส PlaylistWithSongs ที่สร้างโมเดลความสัมพันธ์แบบหลายต่อหลายระหว่างคลาสเอนทิตี Playlist กับคลาสเอนทิตี Song
data class PlaylistWithSongs( @Embedded val playlist: Playlist, @Relation( parentColumns = ["playlistId"], entityColumns = ["songId"], associateBy = Junction(PlaylistSongCrossRef::class) ) val songs: List<Song> )
หลังจากกำหนดคลาสข้อมูลที่แสดงความสัมพันธ์นี้แล้ว ให้สร้างคลาสข้อมูลอีกคลาสหนึ่งที่สร้างโมเดลความสัมพันธ์ระหว่างตารางอื่นจากชุดกับคลาสความสัมพันธ์แรก โดย "ซ้อน" ความสัมพันธ์ที่มีอยู่ภายในความสัมพันธ์ใหม่ ตัวอย่างต่อไปนี้แสดงคลาส UserWithPlaylistsAndSongs ที่สร้างโมเดล
ความสัมพันธ์แบบหนึ่งต่อหลายระหว่างคลาสเอนทิตี User กับ
PlaylistWithSongs คลาสความสัมพันธ์:
data class UserWithPlaylistsAndSongs( @Embedded val user: User, @Relation( entity = Playlist::class, parentColumns = ["userId"], entityColumns = ["userCreatorId"] ) val playlists: List<PlaylistWithSongs> )
คลาส UserWithPlaylistsAndSongs สร้างโมเดลความสัมพันธ์
ระหว่างคลาสเอนทิตีทั้ง 3 คลาส ได้แก่ User, Playlist, และ Song โดยอ้อม ซึ่งแสดงไว้ในรูปที่ 1
หากชุดมีตารางมากกว่านี้ ให้สร้างคลาสเพื่อสร้างโมเดลความสัมพันธ์ระหว่างตารางที่เหลือแต่ละรายการกับคลาสความสัมพันธ์ก่อนหน้า กระบวนการนี้จะสร้างความสัมพันธ์แบบซ้อนเป็นห่วงโซ่ระหว่างตารางทั้งหมดที่คุณต้องการค้นหา
สุดท้าย ให้เพิ่มฟังก์ชันลงในคลาสออบเจ็กต์การเข้าถึงข้อมูล (DAO) เพื่อแสดงฟังก์ชันการค้นหาที่แอปต้องการ ฟังก์ชันนี้กำหนดให้ Room ต้องเรียกใช้
การค้นหาหลายรายการ ดังนั้นให้เพิ่มคำอธิบายประกอบ @Transaction เพื่อให้การดำเนินการทั้งหมด
ทำงานแบบอะตอมมิก:
@Transaction @Query("SELECT * FROM User") suspend fun getUsersWithPlaylistsAndSongs(): List<UserWithPlaylistsAndSongs>