حفظ البيانات في قاعدة بيانات محلية باستخدام الغرفة جزء من Android Jetpack.

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

توفر مكتبة بقاء الغرفة طبقة تجريدية فوق SQLite للسماح الوصول إلى قاعدة البيانات بطلاقة مع الاستفادة من الإمكانيات الكاملة لـ SQLite. وعلى وجه الخصوص، توفّر الغرفة المزايا التالية:

  • التحقق من وقت التجميع لاستعلامات SQL.
  • تعليقات توضيحية ملائمة تقلّل من النصوص النموذجية المتكرّرة والمعرَّضة للأخطاء الرمز.
  • مسارات نقل بيانات مبسّطة لقواعد البيانات

بناءً على هذه الاعتبارات، ننصحك بشدة باستخدام الغرفة بدلاً من ذلك. استخدام واجهات برمجة تطبيقات SQLite مباشرةً.

ضبط إعدادات الجهاز

لاستخدام الغرفة في تطبيقك، أضِف العناصر الاعتمادية التالية إلى قسم تطبيقك. ملف build.gradle:

Groovy

dependencies {
    def room_version = "2.6.1"

    implementation "androidx.room:room-runtime:$room_version"
    annotationProcessor "androidx.room:room-compiler:$room_version"

    // To use Kotlin annotation processing tool (kapt)
    kapt "androidx.room:room-compiler:$room_version"
    // To use Kotlin Symbol Processing (KSP)
    ksp "androidx.room:room-compiler:$room_version"

    // optional - RxJava2 support for Room
    implementation "androidx.room:room-rxjava2:$room_version"

    // optional - RxJava3 support for Room
    implementation "androidx.room:room-rxjava3:$room_version"

    // optional - Guava support for Room, including Optional and ListenableFuture
    implementation "androidx.room:room-guava:$room_version"

    // optional - Test helpers
    testImplementation "androidx.room:room-testing:$room_version"

    // optional - Paging 3 Integration
    implementation "androidx.room:room-paging:$room_version"
}

Kotlin

dependencies {
    val room_version = "2.6.1"

    implementation("androidx.room:room-runtime:$room_version")
    annotationProcessor("androidx.room:room-compiler:$room_version")

    // To use Kotlin annotation processing tool (kapt)
    kapt("androidx.room:room-compiler:$room_version")
    // To use Kotlin Symbol Processing (KSP)
    ksp("androidx.room:room-compiler:$room_version")

    // optional - Kotlin Extensions and Coroutines support for Room
    implementation("androidx.room:room-ktx:$room_version")

    // optional - RxJava2 support for Room
    implementation("androidx.room:room-rxjava2:$room_version")

    // optional - RxJava3 support for Room
    implementation("androidx.room:room-rxjava3:$room_version")

    // optional - Guava support for Room, including Optional and ListenableFuture
    implementation("androidx.room:room-guava:$room_version")

    // optional - Test helpers
    testImplementation("androidx.room:room-testing:$room_version")

    // optional - Paging 3 Integration
    implementation("androidx.room:room-paging:$room_version")
}

المكوّنات الأساسية

تتوفر ثلاثة مكونات رئيسية في الغرفة:

توفّر فئة قاعدة البيانات لتطبيقك أمثلة على DAO المرتبطة قاعدة البيانات هذه. وبالتالي، يمكن للتطبيق استخدام أجهزة DAO لاسترداد البيانات من قاعدة البيانات كمثيلات لكائنات كيان البيانات المرتبطة. يمكن للتطبيق أيضًا استخدام كيانات البيانات المحددة لتعديل الصفوف من الجداول المقابلة، أو لإنشاء صفوف جديدة لإدراجها. يوضح الشكل 1 العلاقة بين المكونات المختلفة للغرفة.

الشكل 1. مخطّط بياني يعرض بنية مكتبة الغرف

نموذج التنفيذ

يقدم هذا القسم مثالاً لتنفيذ قاعدة بيانات غرفة باستخدام DAO واحد.

كيان البيانات

يحدّد الرمز التالي كيان بيانات User. كل مثيل من User يمثل صفًا في جدول user في قاعدة بيانات التطبيق.

Kotlin

@Entity
data class User(
    @PrimaryKey val uid: Int,
    @ColumnInfo(name = "first_name") val firstName: String?,
    @ColumnInfo(name = "last_name") val lastName: String?
)

Java

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

    @ColumnInfo(name = "first_name")
    public String firstName;

    @ColumnInfo(name = "last_name")
    public String lastName;
}

لمعرفة مزيد من المعلومات حول كيانات البيانات في الغرفة، يُرجى الاطّلاع على المقالة تعريف البيانات باستخدام الغرفة. والكيانات.

عنصر الوصول إلى البيانات (DAO)

يحدد الرمز التالي جهاز DAO يسمى UserDao. توفّر السمة UserDao الطرق التي يستخدمها باقي التطبيق للتفاعل مع البيانات في جدول user.

Kotlin

@Dao
interface UserDao {
    @Query("SELECT * FROM user")
    fun getAll(): List<User>

    @Query("SELECT * FROM user WHERE uid IN (:userIds)")
    fun loadAllByIds(userIds: IntArray): List<User>

    @Query("SELECT * FROM user WHERE first_name LIKE :first AND " +
           "last_name LIKE :last LIMIT 1")
    fun findByName(first: String, last: String): User

    @Insert
    fun insertAll(vararg users: User)

    @Delete
    fun delete(user: User)
}

Java

@Dao
public interface UserDao {
    @Query("SELECT * FROM user")
    List<User> getAll();

    @Query("SELECT * FROM user WHERE uid IN (:userIds)")
    List<User> loadAllByIds(int[] userIds);

    @Query("SELECT * FROM user WHERE first_name LIKE :first AND " +
           "last_name LIKE :last LIMIT 1")
    User findByName(String first, String last);

    @Insert
    void insertAll(User... users);

    @Delete
    void delete(User user);
}

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

قاعدة البيانات

يحدّد الرمز التالي فئة AppDatabase للاحتفاظ بقاعدة البيانات. تُحدِّد ميزة "AppDatabase" إعدادات قاعدة البيانات وتعمل كأداة رئيسية نقطة وصول إلى البيانات المحفوظة. يجب أن تفي فئة قاعدة البيانات بـ الشروط التالية:

  • يجب إضافة تعليق توضيحي للفئة @Database تعليق توضيحي يتضمّن entities تسرد جميع كيانات البيانات المرتبطة بقاعدة البيانات.
  • يجب أن تكون الفئة فئة مجردة تمتد RoomDatabase
  • لكل فئة DAO مرتبطة بقاعدة البيانات، يجب أن تكون فئة قاعدة البيانات طريقة مجردة لا تحتوي على أي وسيطات وتعرض مثيلاً لفئة DAO.

Kotlin

@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao
}

Java

@Database(entities = {User.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
    public abstract UserDao userDao();
}

ملاحظة: إذا كان تطبيقك يعمل في عملية واحدة، يجب اتّباع ما يلي: نمط تصميم فرديتون عند إنشاء مثيل لـ AppDatabase الخاص بك. كل مثيل في RoomDatabase مكلف إلى حد ما، ويتعين عليك الوصول إلى مثيلات متعددة ضمن عملية واحدة.

إذا كان تطبيقك يعمل في عمليات متعددة، عليك تضمين: enableMultiInstanceInvalidation() في أداة إنشاء قواعد البيانات . بهذه الطريقة، عندما يكون لديك مثيل AppDatabase في كل عملية، يمكنك إلغاء صلاحية ملف قاعدة البيانات المشتركة في عملية واحدة، ويتم نشر هذا الإلغاء تلقائيًا في مثيلات AppDatabase ضمن العمليات الأخرى.

الاستخدام

بعد أن تحدد كيان البيانات وDAO وكائن قاعدة البيانات، يمكننا استخدام التعليمة البرمجية التالية لإنشاء مثيل قاعدة البيانات:

Kotlin

val db = Room.databaseBuilder(
            applicationContext,
            AppDatabase::class.java, "database-name"
        ).build()

Java

AppDatabase db = Room.databaseBuilder(getApplicationContext(),
        AppDatabase.class, "database-name").build();

ويمكنك بعد ذلك استخدام الأساليب المجرّدة من AppDatabase للحصول على مثال. من DAO. في المقابل، يمكنك استخدام الطرق من مثيل DAO للتفاعل مع قاعدة البيانات:

Kotlin

val userDao = db.userDao()
val users: List<User> = userDao.getAll()

Java

UserDao userDao = db.userDao();
List<User> users = userDao.getAll();

مصادر إضافية

لمزيد من المعلومات عن الغرفة، يُرجى الاطّلاع على المراجع الإضافية التالية:

نماذج

الدروس التطبيقية حول الترميز

المدوّنات