تعریف و پرس و جو روابط چند به چند، تعریف و پرس و جو از روابط چند به چند

رابطه چند به چند بین دو موجودیت، رابطه ای است که در آن هر نمونه از موجودیت اصلی با صفر یا چند نمونه از موجودیت فرزند مطابقت دارد و عکس آن نیز صادق است.

در مثال برنامه پخش موسیقی، آهنگ های موجود در لیست پخش تعریف شده توسط کاربر را در نظر بگیرید. هر لیست پخش می تواند شامل آهنگ های زیادی باشد و هر آهنگ می تواند بخشی از لیست های پخش مختلف باشد. بنابراین، بین موجودیت Playlist و موجودیت Song رابطه بسیار به چند وجود دارد.

این مراحل را برای تعریف و پرس و جوی روابط چند به چند در پایگاه داده خود دنبال کنید:

  1. تعریف رابطه : نهادها و موجودیت انجمنی (جدول مرجع متقابل) را برای نشان دادن رابطه چند به چند ایجاد کنید.
  2. Query the entities : تعیین کنید که چگونه می خواهید از موجودیت های مرتبط پرس و جو کنید و کلاس های داده ای را برای نمایش خروجی مورد نظر ایجاد کنید.

رابطه را تعریف کنید

برای تعریف رابطه چند به چند، ابتدا برای هر یک از دو موجودیت خود یک کلاس ایجاد کنید. روابط چند به چند از دیگر انواع روابط متمایز هستند زیرا به طور کلی هیچ اشاره ای به موجودیت والد در موجودیت فرزند وجود ندارد. در عوض، یک کلاس سوم برای نشان دادن یک موجودیت انجمنی یا جدول مرجع متقابل بین دو موجود ایجاد کنید. جدول مرجع متقابل باید دارای ستون هایی برای کلید اصلی از هر موجودیت در رابطه چند به چند نشان داده شده در جدول باشد. در این مثال، هر ردیف در جدول ارجاع متقابل مربوط به جفتی از یک 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 اضافه کنید تا تابع query مورد نیاز برنامه شما را نشان دهد.

  • 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();
،

رابطه چند به چند بین دو موجودیت، رابطه ای است که در آن هر نمونه از موجودیت اصلی با صفر یا چند نمونه از موجودیت فرزند مطابقت دارد و عکس آن نیز صادق است.

در مثال برنامه پخش موسیقی، آهنگ های موجود در لیست پخش تعریف شده توسط کاربر را در نظر بگیرید. هر لیست پخش می تواند شامل آهنگ های زیادی باشد و هر آهنگ می تواند بخشی از لیست های پخش مختلف باشد. بنابراین، بین موجودیت Playlist و موجودیت Song رابطه بسیار به چند وجود دارد.

این مراحل را برای تعریف و پرس و جوی روابط چند به چند در پایگاه داده خود دنبال کنید:

  1. تعریف رابطه : نهادها و موجودیت انجمنی (جدول مرجع متقابل) را برای نشان دادن رابطه چند به چند ایجاد کنید.
  2. Query the entities : تعیین کنید که چگونه می خواهید از موجودیت های مرتبط پرس و جو کنید و کلاس های داده ای را برای نمایش خروجی مورد نظر ایجاد کنید.

رابطه را تعریف کنید

برای تعریف رابطه چند به چند، ابتدا برای هر یک از دو موجودیت خود یک کلاس ایجاد کنید. روابط چند به چند از دیگر انواع روابط متمایز هستند زیرا به طور کلی هیچ اشاره ای به موجودیت والد در موجودیت فرزند وجود ندارد. در عوض، یک کلاس سوم برای نشان دادن یک موجودیت انجمنی یا جدول مرجع متقابل بین دو موجود ایجاد کنید. جدول مرجع متقابل باید دارای ستون هایی برای کلید اصلی از هر موجودیت در رابطه چند به چند نشان داده شده در جدول باشد. در این مثال، هر ردیف در جدول ارجاع متقابل مربوط به جفتی از یک 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 اضافه کنید تا تابع query مورد نیاز برنامه شما را نشان دهد.

  • 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();