اختيار أنواع العلاقات بين العناصر

بما أنّ SQLite هي قاعدة بيانات ارتباطية، يمكنك تحديد العلاقات بين الكيانات. ومع ذلك، في حين أنّ معظم مكتبات ربط البيانات العلائقية بالكائنات تتيح للكائنات الممثِّلة للكيانات الإشارة إلى بعضها البعض، فإنّ Room تحظر ذلك صراحةً. للتعرّف على الأسباب الفنية وراء هذا القرار، يمكنك الاطّلاع على فهم سبب عدم سماح Room بمراجع الكائنات.

أنواع العلاقات

يتيح Room أنواع العلاقات التالية:

اختيار إحدى الطريقتَين

في Room، هناك طريقتان لتحديد علاقة بين عناصر والبحث عنها. يمكنك استخدام أيّ مما يلي:

  • فئة بيانات وسيطة تحتوي على عناصر مضمّنة
  • طريقة طلب بحث ارتباطي مع نوع القيمة التي تم إرجاعها خريطة متعددة.

إذا لم يكن لديك سبب محدّد لاستخدام فئات البيانات الوسيطة، ننصحك باستخدام أسلوب نوع القيمة التي تم إرجاعها multimap. لمزيد من المعلومات حول هذه الطريقة، يُرجى الاطّلاع على عرض خريطة متعددة.

يتيح لك أسلوب فئة البيانات الوسيطة تجنُّب كتابة طلبات بحث SQL معقّدة، ولكنّه قد يؤدي أيضًا إلى زيادة تعقيد الرموز البرمجية لأنّه يتطلّب فئات بيانات إضافية. باختصار، يتطلّب أسلوب نوع القيمة التي تم إرجاعها المتعدد الخرائط أن تنفّذ طلبات لغة الاستعلامات البنيوية (SQL) المزيد من العمل، ويتطلّب أسلوب فئة البيانات الوسيطة أن ينفّذ الرمز البرمجي المزيد من العمل.

استخدام أسلوب فئة البيانات الوسيطة

في طريقة فئة البيانات الوسيطة، عليك تحديد فئة بيانات تنمذج العلاقة بين عناصر Room. يحتوي فئة البيانات هذه على عمليات الربط بين مثيلات كيان واحد ومثيلات كيان آخر كعناصر مضمّنة. يمكن أن تعرض طرق طلب البحث بعد ذلك مثيلات لفئة البيانات هذه لاستخدامها في تطبيقك.

على سبيل المثال، يمكنك تحديد فئة بيانات 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;
}

استخدام أسلوب أنواع الإرجاع في الخرائط المتعددة

في طريقة نوع القيمة التي تم إرجاعها متعدد الخرائط، لست بحاجة إلى تحديد أي فئات بيانات إضافية. بدلاً من ذلك، يمكنك تحديد نوع القيمة التي تم إرجاعها multimap للطريقة استنادًا إلى بنية الخريطة التي تريدها وتحديد العلاقة بين الكيانات مباشرةً في طلب بحث لغة الاستعلامات البنيوية (SQL).

على سبيل المثال، تعرض طريقة طلب البحث التالية عملية ربط بين مثيلات 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، راجِع المراجع الإضافية التالية.

الفيديوهات

المدوّنات