يمكنك حفظ البيانات في قاعدة بيانات محلية باستخدام Room جزء من Android Jetpack.
يمكن للتطبيقات التي تتعامل مع كميات بسيطة من البيانات المنظَّمة أن تستفيد بشكل كبير من الاحتفاظ بالبيانات على المستوى المحلي. تتمثل حالة الاستخدام الأكثر شيوعًا في تخزين أجزاء البيانات ذات الصلة بحيث لا يتمكن الجهاز من الوصول إلى الشبكة، ويظل المستخدم يتصفح هذا المحتوى أثناء عدم اتصاله بالإنترنت.
توفر مكتبة استمرارية الغرفة طبقة تجريد عبر SQLite للسماح بالوصول بطلاقة إلى قاعدة البيانات مع الاستفادة من إمكانيات SQLite الكاملة. على وجه الخصوص، تقدّم Room المزايا التالية:
- التحقق في وقت التجميع من طلبات لغة الاستعلامات البنيوية (SQL)
- التعليقات التوضيحية الملائمة التي تقلل من الرموز النموذجية المتكررة والتي تكون عرضة للأخطاء.
- مسارات نقل بيانات قواعد البيانات مُبسّطة
بسبب هذه الاعتبارات، ننصحك بشدة باستخدام الغرفة بدلاً من استخدام واجهات برمجة تطبيقات SQLite مباشرةً.
ضبط إعدادات
لاستخدام Room في تطبيقك، أضِف العناصر الاعتمادية التالية إلى ملف
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") }
المكونات الأساسية
تتضمّن الغرفة ثلاثة مكونات رئيسية:
- فئة قاعدة البيانات التي تحتفظ بقاعدة البيانات وتعمل كنقطة الوصول الرئيسية للاتصال الأساسي ببيانات تطبيقك المحفوظة.
- كيانات البيانات التي تمثل الجداول في قاعدة بيانات تطبيقك.
- كائنات الوصول إلى البيانات (DAOs) التي توفّر طرقًا يمكن لتطبيقك استخدامها للاستعلام عن البيانات في قاعدة البيانات وتعديلها وإدراجها وحذفها في قاعدة البيانات.
تزود فئة قاعدة البيانات تطبيقك بمثيلات من DAO المرتبطة بقاعدة البيانات تلك. وفي المقابل، يمكن للتطبيق استخدام وحدات DAO لاسترداد البيانات من قاعدة البيانات كمثيلات لكائنات كيان البيانات المرتبطة. يمكن للتطبيق أيضًا استخدام كيانات البيانات المحددة لتحديث الصفوف من الجداول المقابلة، أو إنشاء صفوف جديدة لإدراجها. يوضح الشكل 1 العلاقة بين المكونات المختلفة للغرفة.
![](https://developer.android.com/static/images/training/data-storage/room_architecture.png?authuser=6&hl=ar)
نموذج عملية التنفيذ
يقدم هذا القسم مثالاً على تنفيذ قاعدة بيانات غرفة باستخدام كيان بيانات واحد ونظام 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); }
لمعرفة المزيد من المعلومات عن DAOs، يُرجى الاطّلاع على الوصول إلى البيانات باستخدام DAOs للغرفة.
قاعدة البيانات
يحدّد الرمز التالي فئة 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();
مراجع إضافية
لمعرفة المزيد من المعلومات عن الغرفة، يُرجى الاطّلاع على المراجع الإضافية التالية: