با استفاده از قسمت Room Android Jetpack داده ها را در یک پایگاه داده محلی ذخیره کنید.

برنامه‌هایی که مقادیر غیر جزئی داده‌های ساختاریافته را مدیریت می‌کنند، می‌توانند از ماندگاری آن داده‌ها به صورت محلی سود زیادی ببرند. رایج‌ترین مورد استفاده، ذخیره اطلاعات مربوطه در حافظه پنهان است تا زمانی که دستگاه نمی‌تواند به شبکه دسترسی داشته باشد، کاربر همچنان بتواند آن محتوا را در حالی که آفلاین است مرور کند.

کتابخانه تداوم اتاق یک لایه انتزاعی را روی SQLite فراهم می کند تا در عین استفاده از قدرت کامل SQLite، به پایگاه داده روان دسترسی داشته باشد. به طور خاص، Room مزایای زیر را ارائه می دهد:

  • تأیید زمان کامپایل پرس و جوهای SQL.
  • حاشیه نویسی راحت که کد دیگ بخار تکراری و مستعد خطا را به حداقل می رساند.
  • مسیرهای مهاجرت پایگاه داده ساده.

به دلیل این ملاحظات، ما به شدت توصیه می کنیم که به جای استفاده مستقیم از API های SQLite از Room استفاده کنید.

راه اندازی

برای استفاده از Room در برنامه خود، وابستگی های زیر را به فایل build.gradle برنامه خود اضافه کنید.

Kotlin

dependencies {
    val room_version = "2.6.1"

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

    // If this project uses any Kotlin source, use Kotlin Symbol Processing (KSP)
    // See Add the KSP plugin to your project
    ksp("androidx.room:room-compiler:$room_version")

    // If this project only uses Java source, use the Java annotationProcessor
    // No additional plugins are necessary
    annotationProcessor("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")
}

Groovy

dependencies {
    def room_version = "2.6.1"

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

    // If this project uses any Kotlin source, use Kotlin Symbol Processing (KSP)
    // See KSP Quickstart to add KSP to your build
    ksp "androidx.room:room-compiler:$room_version"

    // If this project only uses Java source, use the Java annotationProcessor
    // No additional plugins are necessary
    annotationProcessor "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"
}

اجزای اولیه

سه جزء اصلی در اتاق وجود دارد:

  • کلاس پایگاه داده ای که پایگاه داده را نگه می دارد و به عنوان نقطه دسترسی اصلی برای اتصال زیربنایی به داده های پایدار برنامه شما عمل می کند.
  • موجودیت های داده ای که جداول را در پایگاه داده برنامه شما نشان می دهند.
  • اشیاء دسترسی به داده (DAO) که روش‌هایی را ارائه می‌دهند که برنامه شما می‌تواند از آنها برای جستجو، به‌روزرسانی، درج و حذف داده‌ها در پایگاه داده استفاده کند.

کلاس پایگاه داده نمونه هایی از DAO های مرتبط با آن پایگاه داده را به برنامه شما ارائه می دهد. به نوبه خود، برنامه می تواند از DAO ها برای بازیابی داده ها از پایگاه داده به عنوان نمونه هایی از اشیاء موجودیت داده مرتبط استفاده کند. این برنامه همچنین می تواند از موجودیت های داده تعریف شده برای به روز رسانی ردیف ها از جداول مربوطه یا ایجاد ردیف های جدید برای درج استفاده کند. شکل 1 رابطه بین اجزای مختلف اتاق را نشان می دهد.

شکل 1. نمودار معماری کتابخانه اتاق.

اجرای نمونه

این بخش نمونه ای از اجرای یک پایگاه داده اتاق با یک موجودیت داده و یک DAO را ارائه می دهد.

موجودیت داده

کد زیر یک موجودیت داده User را تعریف می کند. هر نمونه از User نشان دهنده یک ردیف در جدول user در پایگاه داده برنامه است.

کاتلین

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

جاوا

@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 استفاده می کند.

کاتلین

@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)
}

جاوا

@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 را برمی گرداند.

کاتلین

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

جاوا

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

توجه: اگر برنامه شما در یک فرآیند اجرا می‌شود، هنگام نمونه‌برداری از یک شی AppDatabase باید از الگوی طراحی singleton پیروی کنید. هر نمونه RoomDatabase نسبتاً گران است و به ندرت نیاز به دسترسی به چندین نمونه در یک فرآیند واحد دارید.

اگر برنامه شما در چندین فرآیند اجرا می شود، enableMultiInstanceInvalidation() در فراخوانی سازنده پایگاه داده خود قرار دهید. به این ترتیب، هنگامی که در هر فرآیند یک نمونه از AppDatabase دارید، می توانید فایل پایگاه داده مشترک را در یک فرآیند باطل کنید و این عدم اعتبار به طور خودکار به نمونه های AppDatabase در سایر فرآیندها منتشر می شود.

استفاده

پس از اینکه موجودیت داده، DAO و شی پایگاه داده را تعریف کردید، می توانید از کد زیر برای ایجاد یک نمونه از پایگاه داده استفاده کنید:

کاتلین

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

جاوا

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

سپس می توانید از روش های انتزاعی از AppDatabase برای دریافت نمونه ای از DAO استفاده کنید. به نوبه خود، می توانید از روش های نمونه DAO برای تعامل با پایگاه داده استفاده کنید:

کاتلین

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

جاوا

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

منابع اضافی

برای کسب اطلاعات بیشتر درباره اتاق، به منابع اضافی زیر مراجعه کنید:

نمونه ها

Codelabs

وبلاگ ها