Terkadang, Anda mungkin perlu membuat kueri kumpulan tiga tabel atau lebih yang semuanya saling berkaitan. Dalam hal ini, Anda menentukan hubungan bertingkat antara tabel.
Misalkan dalam contoh aplikasi streaming musik, Anda ingin membuat kueri semua pengguna, semua playlist untuk setiap pengguna, dan semua lagu di setiap playlist untuk setiap pengguna. Pengguna memiliki hubungan one-to-many dengan playlist, dan playlist memiliki hubungan many-to-many dengan lagu. Contoh kode berikut menunjukkan class yang mewakili entity ini, serta tabel referensi silang untuk hubungan many-to-many antara playlist dan lagu:
@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 )
Pertama, buat model hubungan antara dua tabel dalam kumpulan seperti
yang biasa Anda lakukan, menggunakan class data dan anotasi @Relation.
Contoh berikut menunjukkan class PlaylistWithSongs yang memodelkan hubungan
many-to-many antara class entity Playlist dan class entity Song:
data class PlaylistWithSongs( @Embedded val playlist: Playlist, @Relation( parentColumns = ["playlistId"], entityColumns = ["songId"], associateBy = Junction(PlaylistSongCrossRef::class) ) val songs: List<Song> )
Setelah Anda menentukan class data yang merepresentasikan hubungan ini, buat class data
lain yang memodelkan hubungan antara tabel lain dari kumpulan dan
class hubungan pertama, "menyarangkan" hubungan yang ada ke dalam hubungan yang
baru. Contoh berikut menunjukkan class UserWithPlaylistsAndSongs yang memodelkan
hubungan one-to-many di antara class entity User dan
class hubungan PlaylistWithSongs:
data class UserWithPlaylistsAndSongs( @Embedded val user: User, @Relation( entity = Playlist::class, parentColumns = ["userId"], entityColumns = ["userCreatorId"] ) val playlists: List<PlaylistWithSongs> )
Class UserWithPlaylistsAndSongs secara tidak langsung memodelkan hubungan
antara ketiga class entity: User, Playlist, dan Song. Hal ini
diilustrasikan dalam gambar 1.
Jika kumpulan Anda memiliki lebih banyak tabel, buat class untuk memodelkan hubungan antara setiap tabel yang tersisa dan class hubungan sebelumnya. Proses ini akan membuat rantai hubungan bertingkat di antara semua tabel yang ingin Anda kueri.
Terakhir, tambahkan fungsi ke class objek akses data (DAO) untuk menampilkan
fungsi kueri yang diperlukan aplikasi Anda. Fungsi ini memerlukan Room untuk menjalankan
beberapa kueri, jadi tambahkan anotasi @Transaction sehingga seluruh
operasi dijalankan secara atomik:
@Transaction @Query("SELECT * FROM User") suspend fun getUsersWithPlaylistsAndSongs(): List<UserWithPlaylistsAndSongs>