في بعض الأحيان، قد تحتاج إلى طلب مجموعة من ثلاثة جداول أو أكثر مرتبطة ببعضها البعض. في هذه الحالة، يمكنك تحديد العلاقات المتداخلة بين الجداول.
لنفترض أنّك تريد في مثال تطبيق بث الموسيقى طلب جميع المستخدمين وجميع قوائم التشغيل لكل مستخدم وجميع الأغاني في كل قائمة تشغيل لكل مستخدم. للمستخدمين علاقة رأس بأطراف مع قوائم التشغيل، و لها علاقة أطراف بأطراف مع الأغاني. يعرض مثال الرمز البرمجي التالي الفئات التي تمثّل هذه الكيانات بالإضافة إلى جدول المراجع التبادلية للعلاقة أطراف بأطراف بين قوائم التشغيل والأغاني:
@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 )
أولاً، يمكنك وضع نموذج للعلاقة بين جدولَين من مجموعة الجداول بالطريقة العادية، باستخدام فئة بيانات والتعليق التوضيحي @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 بشكل غير مباشر العلاقات
بين جميع فئات الكيانات الثلاث: User وPlaylist وSong. يوضّح الشكل 1 ذلك.
إذا كانت مجموعتك تتضمّن جداول أكثر، يمكنك إنشاء فئة لتمثيل العلاقة بين كل جدول متبقٍ وفئة العلاقة السابقة. تؤدي هذه العملية إلى إنشاء سلسلة من العلاقات المتداخلة بين جميع الجداول التي تريد طلبها.
أخيرًا، أضف دالة إلى فئة كائن الوصول إلى البيانات (DAO) لعرض دالة الاستعلام التي يحتاجها تطبيقك. تتطلّب هذه الدالة أن ينفّذ Room طلبات متعدّدة، لذا يمكنك إضافة التعليق التوضيحي @Transaction لكي يتم تشغيل العملية بأكملها بشكل ذري:
@Transaction @Query("SELECT * FROM User") suspend fun getUsersWithPlaylistsAndSongs(): List<UserWithPlaylistsAndSongs>