العلاقة بين عناصر متعددة هي علاقة ترتبط فيها كل مثيل من العنصر الرئيسي بصفر أو أكثر من المثيلات للعنصر الثانوي، وينطبق العكس أيضًا.
في مثال تطبيق بث الموسيقى، نأخذ الأغاني في
قوائم التشغيل التي يحدّدها المستخدمون في الاعتبار. يمكن أن تتضمّن كل قائمة تشغيل العديد من الأغاني، ويمكن أن تكون كل أغنية جزءًا من
قوائم تشغيل مختلفة. وبالتالي، هناك علاقة أطراف بأطراف
بين عنصر Playlist
وعنصر Song
.
اتّبِع الخطوات التالية لتحديد العلاقات بين عناصر متعددة في قاعدة البيانات وإجراء طلبات بحث بشأنها:
- تحديد العلاقة: حدِّد الكيانات والكينان الرابط (جدول الإحالات المتبادلة) لتمثيل العلاقة بين أطراف بأطراف.
- طلب البحث عن الكيانات: حدِّد الطريقة التي تريد بها طلب البحث عن الكيانات ذات الصلة وأنشئ فئات بيانات لتمثيل الإخراج المقصود.
تحديد العلاقة
لتحديد علاقة بين عناصر متعددة، أنشئ أولاً فئة لكل من
العنصرَين. تختلف العلاقات بين عناصر متعددة عن أنواع العلاقات الأخرى
لأنّه لا تتم الإشارة بشكل عام إلى العنصر الرئيسي في العنصر
الفرعي. بدلاً من ذلك، أنشئ فئة ثالثة لتمثيل كيان
مرتبط أو جدول مراجع متقاطعة بين الكيانَين.
يجب أن يحتوي جدول المراجع المتقاطعة على أعمدة للمفتاح الأساسي من كل عنصر
في العلاقة بين عناصر متعددة والممثّلة في الجدول. في هذا المثال، يتطابق كل
صف في جدول المراجع المتقاطعة مع إقران مثيل Playlist
ومثيل Song
حيث يتم تضمين الأغنية المُشار إليها في
قائمة التشغيل المُشار إليها.
Kotlin
@Entity
data class Playlist(
@PrimaryKey val playlistId: Long,
val playlistName: String
)
@Entity
data class Song(
@PrimaryKey val songId: Long,
val songName: String,
val artist: String
)
@Entity(primaryKeys = ["playlistId", "songId"])
data class PlaylistSongCrossRef(
val playlistId: Long,
val songId: Long
)
Java
@Entity
public class Playlist {
@PrimaryKey public long playlistId;
public String playlistName;
}
@Entity
public class Song {
@PrimaryKey public long songId;
public String songName;
public String artist;
}
@Entity(primaryKeys = {"playlistId", "songId"})
public class PlaylistSongCrossRef {
public long playlistId;
public long songId;
}
طلب الكيانات
تعتمد الخطوة التالية على الطريقة التي تريد بها إجراء طلب بحث عن هذه الكيانات ذات الصلة.
- إذا أردت طلب قوائم التشغيل وقائمة الأغاني المقابلة لكل
قائمة تشغيل، أنشئ فئة بيانات جديدة تحتوي على عنصر
Playlist
واحد وقائمة بكل عناصرSong
التي تتضمّنها قائمة التشغيل. - إذا أردت البحث عن أغانٍ وقائمة قوائم تشغيل مقابلة لكل منها، أنشئ فئة بيانات جديدة تحتوي على عنصر
Song
واحد وقائمة بكل عناصرPlaylist
التي تتضمّن الأغنية.
في كلتا الحالتَين، يمكنك وضع نموذج للعلاقة بين الكيانَين باستخدام السمة
associateBy
في التعليق التوضيحي @Relation
في كلّ من
هذه الفئتَين لتحديد عنصر المرجع المتقاطع الذي يوضّح العلاقة
بين عنصر Playlist
وعنصر Song
.
Kotlin
data class PlaylistWithSongs(
@Embedded val playlist: Playlist,
@Relation(
parentColumn = "playlistId",
entityColumn = "songId",
associateBy = Junction(PlaylistSongCrossRef::class)
)
val songs: List<Song>
)
data class SongWithPlaylists(
@Embedded val song: Song,
@Relation(
parentColumn = "songId",
entityColumn = "playlistId",
associateBy = Junction(PlaylistSongCrossRef::class)
)
val playlists: List<Playlist>
)
Java
public class PlaylistWithSongs {
@Embedded public Playlist playlist;
@Relation(
parentColumn = "playlistId",
entityColumn = "songId",
associateBy = @Junction(PlaylistSongCrossref.class)
)
public List<Song> songs;
}
public class SongWithPlaylists {
@Embedded public Song song;
@Relation(
parentColumn = "songId",
entityColumn = "playlistId",
associateBy = @Junction(PlaylistSongCrossref.class)
)
public List<Playlist> playlists;
}
أخيرًا، أضِف طريقة إلى فئة DAO لعرض دالة طلب البحث التي يحتاج إليها تطبيقك.
getPlaylistsWithSongs
: تُجري هذه الطريقة طلب بحث في قاعدة البيانات وتُعيد كل عناصرPlaylistWithSongs
الناتجة.getSongsWithPlaylists
: تُجري هذه الطريقة طلب بحث في قاعدة البيانات وتُرجع كل عناصرSongWithPlaylists
الناتجة.
تتطلّب كلتا الطريقتَين من Room تنفيذ طلبَي بحث، لذا أضِف التعليق التوضيحي
@Transaction
إلى كلتا الطريقتَين لكي تتم تنفيذ العملية
كلها بشكلٍ موحّد.
Kotlin
@Transaction
@Query("SELECT * FROM Playlist")
fun getPlaylistsWithSongs(): List<PlaylistWithSongs>
@Transaction
@Query("SELECT * FROM Song")
fun getSongsWithPlaylists(): List<SongWithPlaylists>
Java
@Transaction
@Query("SELECT * FROM Playlist")
public List<PlaylistWithSongs> getPlaylistsWithSongs();
@Transaction
@Query("SELECT * FROM Song")
public List<SongWithPlaylists> getSongsWithPlaylists();