कई-से-कई रिलेशनशिप तय करना और उनसे जुड़ी क्वेरी करना

दो इकाइयों के बीच कई-से-कई संबंध एक ऐसा संबंध होता है जहां पैरंट इकाई का हर इंस्टेंस, चाइल्ड इकाई के शून्य या उससे ज़्यादा इंस्टेंस से जुड़ा होता है. इसके अलावा, यह भी सच है कि चाइल्ड इकाई का हर इंस्टेंस, पैरंट इकाई के शून्य या उससे ज़्यादा इंस्टेंस से जुड़ा होता है.

संगीत स्ट्रीमिंग ऐप्लिकेशन के उदाहरण में, उपयोगकर्ता की बनाई गई प्लेलिस्ट में मौजूद गाने देखें. हर प्लेलिस्ट में कई गाने शामिल किए जा सकते हैं. साथ ही, हर गाना कई अलग-अलग प्लेलिस्ट का हिस्सा हो सकता है. इसलिए, Playlist इकाई और Song इकाई के बीच, कई-से-कई रिलेशनशिप है.

अपने डेटाबेस में कई-से-कई रिलेशनशिप तय करने और उनसे जुड़ी क्वेरी करने के लिए, यह तरीका अपनाएं:

  1. रिश्ते को तय करना: कई-से-कई संबंध दिखाने के लिए, इकाइयों और असोसिएटिव इकाई (क्रॉस-रेफ़रंस टेबल) को सेट अप करें.
  2. इकाइयों से जुड़ी क्वेरी करें: तय करें कि आपको मिलती-जुलती इकाइयों से जुड़ी क्वेरी कैसे करनी है. साथ ही, अपने हिसाब से आउटपुट दिखाने के लिए डेटा क्लास बनाएं.

संबंध तय करना

कई-से-कई संबंध तय करने के लिए, सबसे पहले अपनी दोनों इकाइयों के लिए एक क्लास बनाएं. कई-से-कई रिलेशनशिप, अन्य तरह की रिलेशनशिप से अलग होती हैं, क्योंकि आम तौर पर चाइल्ड इकाई में पैरंट इकाई का कोई रेफ़रंस नहीं होता. इसके बजाय, दोनों इकाइयों के बीच असोसिएटिव इकाई या क्रॉस-रेफ़रंस टेबल को दिखाने के लिए, तीसरी क्लास बनाएं. क्रॉस-रेफ़रंस टेबल में, टेबल में दिखाए गए कई-से-कई संबंध में, हर इकाई की प्राइमरी कुंजी के लिए कॉलम होने चाहिए. इस उदाहरण में, क्रॉस-रेफ़रंस टेबल की हर पंक्ति, 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 ऑब्जेक्ट की सूची शामिल होनी चाहिए जिनमें गाना शामिल है.

दोनों ही मामलों में, Playlist इकाई और Song इकाई के बीच के संबंध की जानकारी देने वाली क्रॉस-रेफ़रंस इकाई की पहचान करने के लिए, इन दोनों क्लास में @Relation एनोटेशन में associateBy प्रॉपर्टी का इस्तेमाल करके, इकाइयों के बीच के संबंध को मॉडल करें.

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;
}

आखिर में, डीएओ क्लास में एक तरीका जोड़ें, ताकि आपके ऐप्लिकेशन के लिए क्वेरी फ़ंक्शन को एक्सपोज़ किया जा सके.

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