ऑब्जेक्ट के बीच संबंध के टाइप चुनना

SQLite एक रिलेशनल डेटाबेस है. इसलिए, इकाइयों के बीच संबंध तय किए जा सकते हैं. हालांकि, ज़्यादातर ऑब्जेक्ट-रिलेशनल मैपिंग लाइब्रेरी, इकाई ऑब्जेक्ट को एक-दूसरे का रेफ़रंस देने की अनुमति देती हैं, लेकिन Room साफ़ तौर पर इसकी अनुमति नहीं देता. इस फ़ैसले के पीछे की तकनीकी वजह जानने के लिए, जानें कि Room में ऑब्जेक्ट रेफ़रंस की अनुमति क्यों नहीं है लेख पढ़ें.

अलग-अलग तरह के संबंध

Room में इस तरह के संबंधों का इस्तेमाल किया जा सकता है:

  • एक-से-एक: इस रिलेशनशिप में, एक इकाई किसी दूसरी इकाई से जुड़ी होती है.
  • वन-टू-मेनी: इस रिलेशनशिप में, एक इकाई किसी दूसरे टाइप की कई इकाइयों से जुड़ी हो सकती है.
  • कई-से-कई: एक ऐसी रिलेशनशिप दिखाता है जिसमें एक टाइप की कई इकाइयां, किसी दूसरे टाइप की कई इकाइयों से जुड़ी हो सकती हैं. आम तौर पर, इसके लिए जंक्शन टेबल की ज़रूरत होती है.
  • नेस्ट की गई रिलेशनशिप (एम्बेड किए गए ऑब्जेक्ट का इस्तेमाल करके): यह ऐसी रिलेशनशिप दिखाती है जिसमें किसी इकाई में फ़ील्ड के तौर पर दूसरी इकाई शामिल होती है. साथ ही, इस नेस्ट की गई इकाई में अन्य इकाइयां भी शामिल हो सकती हैं. इसमें @Embedded एनोटेशन का इस्तेमाल किया जाता है.

दो तरीकों में से किसी एक को चुनना

Room में, इकाइयों के बीच के संबंध को तय करने और उससे जुड़ी क्वेरी करने के दो तरीके हैं. इनमें से किसी एक का इस्तेमाल किया जा सकता है:

  • एम्बेड किए गए ऑब्जेक्ट वाली इंटरमीडियरी डेटा क्लास या
  • रिलेशनल क्वेरी का एक तरीका, जिसमें रिटर्न टाइप के तौर पर मल्टीमैप होता है.

अगर आपके पास इंटरमीडियरी डेटा क्लास का इस्तेमाल करने की कोई खास वजह नहीं है, तो हमारा सुझाव है कि आप मल्टीमैप रिटर्न टाइप के तरीके का इस्तेमाल करें. इस तरीके के बारे में ज़्यादा जानने के लिए, मल्टीमैप दिखाना लेख पढ़ें.

इंटरमीडिएट डेटा क्लास के तरीके से, जटिल एसक्यूएल क्वेरी लिखने से बचा जा सकता है. हालांकि, इससे कोड की जटिलता भी बढ़ सकती है, क्योंकि इसके लिए अतिरिक्त डेटा क्लास की ज़रूरत होती है. कम शब्दों में, मल्टीमैप रिटर्न टाइप के तरीके के लिए, आपकी SQL क्वेरी को ज़्यादा काम करना पड़ता है. वहीं, इंटरमीडिएट डेटा क्लास के तरीके के लिए, आपके कोड को ज़्यादा काम करना पड़ता है.

इंटरमीडिएट डेटा क्लास के तरीके का इस्तेमाल करना

इंटरमीडिएट डेटा क्लास के तरीके में, एक डेटा क्लास तय की जाती है, जो आपकी रूम इकाइयों के बीच के संबंध को मॉडल करती है. इस डेटा क्लास में, एक इकाई के इंस्टेंस और दूसरी इकाई के इंस्टेंस के बीच की जोड़ी को एम्बेड किए गए ऑब्जेक्ट के तौर पर सेव किया जाता है. इसके बाद, आपके ऐप्लिकेशन में इस्तेमाल करने के लिए, क्वेरी के तरीके इस डेटा क्लास के इंस्टेंस दिखा सकते हैं.

उदाहरण के लिए, लाइब्रेरी के उन उपयोगकर्ताओं को दिखाने के लिए UserBook डेटा क्लास तय की जा सकती है जिन्होंने कुछ खास किताबें चेक आउट की हैं. साथ ही, डेटाबेस से UserBook इंस्टेंस की सूची पाने के लिए, क्वेरी का तरीका तय किया जा सकता है:

Kotlin

@Dao
interface UserBookDao {
    @Query(
        "SELECT user.name AS userName, book.name AS bookName " +
        "FROM user, book " +
        "WHERE user.id = book.user_id"
    )
    fun loadUserAndBookNames(): LiveData<List<UserBook>>
}

data class UserBook(val userName: String?, val bookName: String?)

Java

@Dao
public interface UserBookDao {
   @Query("SELECT user.name AS userName, book.name AS bookName " +
          "FROM user, book " +
          "WHERE user.id = book.user_id")
   public LiveData<List<UserBook>> loadUserAndBookNames();
}

public class UserBook {
    public String userName;
    public String bookName;
}

रिटर्न टाइप के मल्टीमैप वाले तरीके का इस्तेमाल करना

मल्टीमैप रिटर्न टाइप के तरीके में, आपको कोई और डेटा क्लास तय करने की ज़रूरत नहीं है. इसके बजाय, अपने मैप के स्ट्रक्चर के आधार पर, अपने तरीके के लिए मल्टीमैप रिटर्न टाइप तय करें. साथ ही, अपनी इकाइयों के बीच के संबंध को सीधे अपनी एसक्यूएल क्वेरी में तय करें.

उदाहरण के लिए, यहां दिया गया क्वेरी तरीका, लाइब्रेरी के उन उपयोगकर्ताओं को दिखाने के लिए User और Book के इंस्टेंस की मैपिंग दिखाता है जिन्होंने कुछ खास किताबें चेक आउट की हैं:

Kotlin

@Query(
    "SELECT * FROM user" +
    "JOIN book ON user.id = book.user_id"
)
fun loadUserAndBookNames(): Map<User, List<Book>>

Java

@Query(
    "SELECT * FROM user" +
    "JOIN book ON user.id = book.user_id"
)
public Map<User, List<Book>> loadUserAndBookNames();

एम्बेड किए गए आइटम बनाना

कभी-कभी, आपको अपने डेटाबेस लॉजिक में किसी इकाई या डेटा ऑब्जेक्ट को एक साथ दिखाना होता है. भले ही, ऑब्जेक्ट में कई फ़ील्ड हों. इन मामलों में, @Embedded एनोटेशन का इस्तेमाल करके, किसी ऐसे ऑब्जेक्ट को दिखाया जा सकता है जिसे आपको टेबल में उसके सबफ़ील्ड में बांटना है. इसके बाद, एम्बेड किए गए फ़ील्ड के लिए वैसी ही क्वेरी की जा सकती है जैसी अन्य कॉलम के लिए की जाती है.

उदाहरण के लिए, आपकी User क्लास में Address टाइप का एक फ़ील्ड शामिल हो सकता है, जो street, city, state, और postCode नाम वाले फ़ील्ड के कॉम्पोज़िशन को दिखाता है. टेबल में, कॉम्पोज़ किए गए कॉलम को अलग से सेव करने के लिए, एक Address फ़ील्ड शामिल करें. यह User क्लास में दिखना चाहिए, जिस पर @Embedded एनोटेट किया गया है. नीचे दिया गया कोड स्निपेट इसका उदाहरण दिखाता है:

Kotlin

data class Address(
    val street: String?,
    val state: String?,
    val city: String?,
    @ColumnInfo(name = "post_code") val postCode: Int
)

@Entity
data class User(
    @PrimaryKey val id: Int,
    val firstName: String?,
    @Embedded val address: Address?
)

Java

public class Address {
    public String street;
    public String state;
    public String city;

    @ColumnInfo(name = "post_code") public int postCode;
}

@Entity
public class User {
    @PrimaryKey public int id;

    public String firstName;

    @Embedded public Address address;
}

इसके बाद, User ऑब्जेक्ट को दिखाने वाली टेबल में ये कॉलम होते हैं: id, firstName, street, state, city, और post_code.

अगर किसी इकाई में एक ही तरह के कई एम्बेड किए गए फ़ील्ड हैं, तो prefix प्रॉपर्टी सेट करके, हर कॉलम को यूनीक रखा जा सकता है. इसके बाद, Room एम्बेड किए गए ऑब्जेक्ट में हर कॉलम के नाम की शुरुआत में दी गई वैल्यू जोड़ता है.

अन्य संसाधन

Room में इकाइयों के बीच संबंधों को तय करने के बारे में ज़्यादा जानने के लिए, यहां दिए गए अन्य संसाधन देखें.

वीडियो

ब्लॉग