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

با کاتلین چند پلتفرمی امتحان کنید
کاتلین چند پلتفرمی امکان اشتراک‌گذاری لایه پایگاه داده با سایر پلتفرم‌ها را فراهم می‌کند. یاد بگیرید چگونه پایگاه داده اتاق را در KMP راه‌اندازی و کار کنید.

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

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

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

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

راه‌اندازی

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

کاتلین

dependencies {
    val room_version = "2.8.4"

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

شیار

dependencies {
    def room_version = "2.8.4"

    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"
}

اجزای اولیه

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

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

کلاس پایگاه داده، نمونه‌هایی از DAOهای مرتبط با آن پایگاه داده را در اختیار برنامه شما قرار می‌دهد. در عوض، برنامه می‌تواند از DAOها برای بازیابی داده‌ها از پایگاه داده به عنوان نمونه‌هایی از اشیاء موجودیت داده مرتبط استفاده کند. برنامه همچنین می‌تواند از موجودیت‌های داده تعریف شده برای به‌روزرسانی ردیف‌ها از جداول مربوطه یا ایجاد ردیف‌های جدید برای درج استفاده کند. شکل 1 رابطه بین اجزای مختلف 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?
)

جاوا

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

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

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

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

شیء دسترسی به داده (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ها، به بخش دسترسی به داده‌ها با استفاده از Room 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();

منابع اضافی

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

نمونه‌ها

کدلبز

وبلاگ‌ها