رابطه چند به چند بین دو موجودیت، رابطهای است که در آن هر نمونه از موجودیت والد با صفر یا چند نمونه از موجودیت فرزند متناظر است و عکس این قضیه نیز صادق است.
در مثال برنامه پخش موسیقی، آهنگهای موجود در لیستهای پخش تعریفشده توسط کاربر را در نظر بگیرید. هر لیست پخش میتواند شامل آهنگهای زیادی باشد و هر آهنگ میتواند بخشی از لیستهای پخش مختلف باشد. بنابراین، یک رابطه چند به چند بین موجودیت Playlist و موجودیت Song وجود دارد.
برای تعریف و پرس و جو از روابط چند به چند در پایگاه داده خود، این مراحل را دنبال کنید:
- تعریف رابطه : موجودیتها و موجودیت انجمنی (جدول ارجاع متقابل) را برای نمایش رابطه چند به چند ایجاد کنید.
- پرسوجو از موجودیتها : مشخص کنید که چگونه میخواهید موجودیتهای مرتبط را پرسوجو کنید و کلاسهای دادهای برای نمایش خروجی مورد نظر ایجاد کنید.
رابطه را تعریف کنید
برای تعریف یک رابطه چند به چند، ابتدا برای هر یک از دو موجودیت خود یک کلاس ایجاد کنید. روابط چند به چند با سایر انواع روابط متمایز هستند زیرا عموماً هیچ ارجاعی به موجودیت والد در موجودیت فرزند وجود ندارد. در عوض، یک کلاس سوم برای نمایش یک موجودیت انجمنی یا جدول ارجاع متقابل بین دو موجودیت ایجاد کنید. جدول ارجاع متقابل باید ستونهایی برای کلید اصلی از هر موجودیت در رابطه چند به چند نشان داده شده در جدول داشته باشد. در این مثال، هر ردیف در جدول ارجاع متقابل مربوط به جفت شدن یک نمونه Playlist و یک نمونه Song است که در آن آهنگ ارجاع شده در لیست پخش ارجاع شده قرار دارد.
کاتلین
@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
)
جاوا
@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 را فراهم میکند، شناسایی شود.
کاتلین
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>
)
جاوا
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 را به هر دو متد اضافه کنید تا کل عملیات به صورت خودکار انجام شود.
کاتلین
@Transaction
@Query("SELECT * FROM Playlist")
fun getPlaylistsWithSongs(): List<PlaylistWithSongs>
@Transaction
@Query("SELECT * FROM Song")
fun getSongsWithPlaylists(): List<SongWithPlaylists>
جاوا
@Transaction
@Query("SELECT * FROM Playlist")
public List<PlaylistWithSongs> getPlaylistsWithSongs();
@Transaction
@Query("SELECT * FROM Song")
public List<SongWithPlaylists> getSongsWithPlaylists();