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

با Kotlin چندپلاتفرمی امتحان کنید
«چندسکویی Kotlin» امکان هم‌رسانی لایه پایگاه داده با پلاتفرم‌های دیگر را فراهم می‌کند. با نحوه راه‌اندازی و کار با «پایگاه داده Room» در KMP آشنا شوید

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

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

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

توصیه می‌کنیم به‌جای استفاده مستقیم از میاناهای برنامه‌سازی کاربردی SQLite، از Room استفاده کنید.

راه‌اندازی

برای استفاده از «اتاق» در برنامه‌تان، وابستگی‌های زیر را به فایل build.gradle.kts واحدتان اضافه کنید. ‫Room 3.0 برای پردازش گزارمان به KSP نیاز دارد.

Kotlin

dependencies {
    val room_version = "3.0.3"

    implementation("androidx.room3:room3-runtime:$room_version")
    ksp("androidx.room3:room3-compiler:$room_version")
}

Groovy

dependencies {
    def room_version = "3.0.3"

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

    ksp "androidx.room3:room3-compiler:$room_version"
}

اجزای اصلی

سه عنصر اصلی در «اتاق» وجود دارد:

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

کلاس پایگاه داده نمونه‌هایی از «اشیا دسترسی به داده» مرتبط با آن پایگاه داده را دراختیار برنامه شما قرار می‌دهد. به‌نوبه خود، برنامه می‌تواند از DAOs برای بازیابی داده‌ها از پایگاه داده به‌عنوان نمونه‌هایی از اشیای نهاد داده مرتبط استفاده کند. این برنامه همچنین می‌تواند از نهادهای داده تعریف‌شده برای به‌روزرسانی ردیف‌ها از جدول‌های مربوطه یا برای ایجاد ردیف‌های جدید برای درج استفاده کند. شکل ۱ رابطه بین اجزای مختلف Room را نشان می‌دهد.

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

پیاده‌سازی نمونه

این بخش نمونه‌ای از پیاده‌سازی پایگاه داده Room با یک نهاد داده و یک 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
)

برای آشنایی بیشتر با نهادهای داده در Room، به تعریف داده‌ها بااستفاده از نهادهای Room مراجعه کنید.

شیء دسترسی به داده (DAO)

کد زیر یک DAO به‌نام UserDao را تعریف می‌کند. UserDao عملکردهایی را که بقیه برنامه برای تعامل با داده‌های جدول user استفاده می‌کنند ارائه می‌دهد.

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

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

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

    @Insert
    suspend fun insertAll(vararg users: User)

    @Delete
    suspend fun delete(user: User)
}

برای کسب اطلاعات بیشتر درباره «اشیا دسترسی به داده‌ها»، به دسترسی به داده‌ها بااستفاده از «اشیا دسترسی به داده‌های Room» مراجعه کنید.

پایگاه داده

کد زیر کلاس AppDatabase را برای نگهداری پایگاه داده تعریف می‌کند. ‫AppDatabase پیکربندی پایگاه داده را تعریف می‌کند و به‌عنوان نقطه دسترسی اصلی برنامه به داده‌های ماندگار عمل می‌کند. کلاس پایگاه داده باید شرایط زیر را داشته باشد:

  • کلاس باید با @Database گزارمانی که شامل entities آرایه‌ای است که همه نهادهای داده مرتبط با پایگاه داده را فهرست می‌کند گزارمان‌گذاری شود.
  • کلاس باید یک کلاس انتزاعی باشد که RoomDatabase را گسترش می‌دهد.
  • برای هر کلاس «شیء دسترسی به داده» مرتبط با پایگاه داده، کلاس پایگاه داده باید تابعی انتزاعی تعریف کند که هیچ آرگومانی را نپذیرد و نمونه‌ای از کلاس «شیء دسترسی به داده» را برگرداند.

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

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

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

کاربرد

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

val db =
    Room.databaseBuilder<AppDatabase>(applicationContext, "database-name")
        .setDriver(AndroidSQLiteDriver())
        .build()

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

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

منابع بیشتر

برای کسب اطلاعات بیشتر درباره «اتاق»، منابع تکمیلی زیر را ببینید:

نمونه‌ها