مقالات

آموزش Room در اندروید: راهنمای استفاده از دیتابیس Room در کاتلین

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

 

 

“ما را در اینستاگرام دنبال کنید”

در این مقاله از سری مقالات برنامه نویسی اندروید اومدیم در مورد Room در اندروید، صحبت کنیم. پس با سایت ترولرن همراه باش.

“قبل از شروع مقاله، بگم که بعد از مطالعه این مطلب، از آموزش پروژه محور برنامه نویسی اندروید سایتمون یعنی دوره ژنرال اندروید غافل نشید.”

توی دوره ژنرال صفر تا صد Room در اندروید رو در یک فصل کامل توضیح دادیم و همچنین توی پروژه های دیجی کالا و اسنپ فود به صورت عملی و پروژه محور از Room استفاده کردیم و بطور کامل اون رو آموزش دادیم.

همه چیز در مورد Room در اندروید

Room DB بر اساس الگوی طراحی ORM (Object-Relational Mapping) عمل می‌کند. این به این معنی است که شما می‌توانید کلاس‌های داده (Entity) خود را تعریف کنید که نمایانگر جداول در دیتابیس SQLite باشند. هر کلاس داده شامل فیلدهایی است که می‌خواهید در دیتابیس ذخیره شوند. Room DB به شما امکان می‌دهد کوئری‌ها را براساس این کلاس‌های داده تعریف کنید و به راحتی با داده‌ها در دیتابیس تعامل کنید.

Room در اندروید همچنین امکاناتی را برای مدیریت نسخه‌های دیتابیس، انجام عملیات در پس‌زمینه و پیمایش اطلاعات فراهم می‌کند. همچنین، شما می‌توانید از استراتژی‌های تعامل با دیتابیس مانند LiveData و Flow و ViewModel نیز در ارتباط با Room DB استفاده کنید تا بهبود عملکرد و قابلیت اطمینان برنامه خود را افزایش دهید.

استفاده از Room DB در اندروید به شما امکان می‌دهد که بهبود عملکرد و بهره‌وری برنامه خود را در کار با داده‌ها افزایش دهید و کدهای تکراری و پیچیده را حذف کنید، روم دی‌بی (Room DB) یک کتابخانه مورد استفاده در برنامه‌نویسی اندروید است که توسعه داده شده توسط گوگل میباشد. این کتابخانه برای کار با دیتابیس SQLite در اندروید طراحی شده و واسطی ساده و قدرتمند برای مدیریت داده‌ها در برنامه‌های اندرویدی فراهم می‌کند.

Room DB از الگوی طراحی ORM برای مدیریت داده‌ها استفاده می‌کند. این الگو به برنامه‌نویسان امکان می‌دهد تا با استفاده از کلاس‌ها و شیء‌گرایی، داده‌های خود را به صورت مستقیم در دیتابیس ذخیره و بازیابی کنند.

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

1. Entity

کلاس Entity نمایانگر جدول‌های دیتابیس است. هر Entity معمولاً یک جدول در دیتابیس را نمایش می‌دهد و فیلدهای آن معمولاً ویژگی‌هایی هستند که در ستون‌های جدول ذخیره می‌شوند.

2. DAO (Data Access Object)

کلاس DAO واسطه‌ای است که متدهایی را برای انجام عملیاتی مانند خواندن، نوشتن، به‌روزرسانی و حذف داده‌ها از دیتابیس ارائه می‌دهد. شما می‌توانید متدهای خاصی را در DAO تعریف کنید و Room DB به طور خودکار پیاده‌سازی آن‌ها را برای شما انجام می‌دهد.

3. Database

کلاس Database نماینده‌ای است که ارتباط با دیتابیس را برقرار می‌کند و DAO‌ها را به شما ارائه می‌دهد. در این کلاس می‌توانید تنظیمات دیتابیس مانند نسخه، مسیر و… را تعریف کنید.

با تعریف این سه مؤلفه، شما می‌توانید از Room DB برای ایجاد، خواندن، به‌روزرسانی و حذف داده‌ها استفاده کنید. همچنین، Room DB از قابلیت‌هایی مانند مدیریت نسخه‌ها، پیمایش داده‌ها و اجرای عملیات در پس‌زمینه نیز پشتیبانی می‌کند.

استفاده از Room در اندروید  باعث ساده‌تر شدن تعامل با دیتابیس SQLite می‌شود و بهبود عملکرد و قابلیت اطمینان برنامه شما را ارتقا می‌بخشد.

 

 

 برای انجام عملیات CRUD در Room DB از چه متدهایی استفاده کنیم؟

با استفاده از کاتلین و معماری MVVM، می‌توانید عملیات CRUD را در Room DB انجام دهید. در زیر یک نمونه ساده از کدهای مربوط به ایجاد، خواندن، به‌روزرسانی و حذف را با استفاده از کاتلین و معماری MVVM نشان می‌دهم:

ابتدا باید مدل داده‌ها را تعریف کنید. به عنوان مثال، فرض کنید یک مدل داده به نام User داریم:

data class User(val id: Int, val name: String, val age: Int)

سپس باید DAO را تعریف کنید. در اینجا فرض می‌کنیم نام DAO ما UserDao است:

@Dao
interface UserDao {
    @Insert
    fun insertUser(user: User)

    @Query("SELECT * FROM users")
    fun getAllUsers(): List<User>

    @Query("SELECT * FROM users WHERE age > :minAge")
    fun getUsersOlderThan(minAge: Int): List<User>

    @Update
    fun updateUser(user: User)

    @Delete
    fun deleteUser(user: User)
}

سپس باید دیتابیس را تعریف کنید. در اینجا فرض می‌کنیم نام دیتابیس ما AppDatabase است:

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

حالا باید ریپازیتوری (Repository) را تعریف کنید، که واسطی بین ViewModel و DAO/Databases است:

class UserRepository(private val userDao: UserDao) {
    fun insertUser(user: User) {
        userDao.insertUser(user)
    }

    fun getAllUsers(): List<User> {
        return userDao.getAllUsers()
    }

    fun getUsersOlderThan(minAge: Int): List<User> {
        return userDao.getUsersOlderThan(minAge)
    }

    fun updateUser(user: User) {
        userDao.updateUser(user)
    }

    fun deleteUser(user: User) {
        userDao.deleteUser(user)
    }
}

حالا باید ViewModel را تعریف کنید. در اینجا فرض می‌کنیم نام ViewModel ما UserViewModel است:

class UserViewModel(private val userRepository: UserRepository) : ViewModel() {
    private val _users = MutableLiveData<List<User>>()
    val users: LiveData<List<User>> get() = _users

    fun insertUser(user: User) {
        userRepository.insertUser(user)
    }

    fun getAllUsers() {
        _users.value = userRepository.getAllUsers()
    }

    fun getUsersOlderThan(minAge: Int) {
        _users.value = userRepository.getUsersOlderThan(minAge)
    }

    fun updateUser(user: User) {
        userRepository.updateUser(user)
    }

    fun deleteUser(user: User) {
        userRepository.deleteUser(user)
    }
}

در نهایت، باید Activity یا Fragment خود را تعریف کنید و ViewModel را استفاده کنید. به عنوان مثال، در یک Activity می‌توانید به صورت زیر عمل کنید:

class MainActivity : AppCompatActivity() {
    private lateinit var userViewModel: UserViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val userDao = AppDatabase.getInstance(application).userDao()
        val userRepository = UserRepository(userDao)
        userViewModel = ViewModelProvider(this).get(UserViewModel::class.java)

        userViewModel.users.observe(this, Observer { users ->
            // در اینجا لیست کاربران به روزرسانی می‌شود
        })

        // مثال استفاده از ViewModel
        val user = User(1, "John Doe", 30)
        userViewModel.insertUser(user)
        userViewModel.getAllUsers()
    }
}

در این مثال، ابتدا ViewModel را با استفاده از ViewModelProvider ایجاد کرده و نمونه از UserRepository را به آن ارسال می‌کنیم. سپس با استفاده از `userViewModel.users.observe` می‌توانید تغییرات در لیست کاربران را مشاهده کنید. در انتها، یک نمونه از کاربر ایجاد می‌کنیم و با استفاده از ViewModel، کاربران را دریافت می‌کنیم.

این مثال تنها یک نمونه ساده از استفاده از کاتلین و معماری MVVM در Room DB است. در پروژه‌های بزرگ‌تر، معمولاً از الگوها و روش‌های متعددی مانند Dependency Injection (DI)، Coroutines و LiveData استفاده می‌شود تا بهبود و بهینه‌سازی کد صورت گیرد.

در این کدها چگونه از کروتینز و flow استفاده کنیم؟

برای استفاده از کروتینز و Flow در کدهای MVVM با کاتلین، می‌توانید تغییرات زیر را انجام دهید:

در DAO، از suspend functions استفاده کنید تا بتوانید کدها را در یک کروتین اجرا کنید. به عنوان مثال:

@Dao
interface UserDao {
    @Insert
    suspend fun insertUser(user: User)

    @Query("SELECT * FROM users")
    fun getAllUsers(): Flow<List<User>>

    @Query("SELECT * FROM users WHERE age > :minAge")
    fun getUsersOlderThan(minAge: Int): Flow<List<User>>

    @Update
    suspend fun updateUser(user: User)

    @Delete
    suspend fun deleteUser(user: User)
}

در ریپازیتوری، از کروتین‌ها برای اجرای توابع suspend استفاده کنید و از Flow همگام‌سازی شده (asFlow) برای تبدیل LiveData به Flow استفاده کنید. به عنوان مثال:

class UserRepository(private val userDao: UserDao) {
    suspend fun insertUser(user: User) {
        userDao.insertUser(user)
    }

    fun getAllUsers(): Flow<List<User>> {
        return userDao.getAllUsers()
    }

    fun getUsersOlderThan(minAge: Int): Flow<List<User>> {
        return userDao.getUsersOlderThan(minAge)
    }

    suspend fun updateUser(user: User) {
        userDao.updateUser(user)
    }

    suspend fun deleteUser(user: User) {
        userDao.deleteUser(user)
    }
}

در ViewModel، از کروتین‌ها برای فراخوانی توابع suspend استفاده کنید و از Flow استفاده کنید تا به جای LiveData از انتشار تغییرات استفاده کنید. به عنوان مثال:

class UserViewModel(private val userRepository: UserRepository) : ViewModel() {
    private val _users = MutableStateFlow<List<User>>(emptyList())
    val users: StateFlow<List<User>> get() = _users

    fun insertUser(user: User) {
        viewModelScope.launch {
            userRepository.insertUser(user)
        }
    }

    fun getAllUsers() {
        viewModelScope.launch {
            userRepository.getAllUsers().collect { users ->
                _users.value = users
            }
        }
    }

    fun getUsersOlderThan(minAge: Int) {
        viewModelScope.launch {
            userRepository.getUsersOlderThan(minAge).collect { users ->
                _users.value = users
            }
        }
    }

    fun updateUser(user: User) {
        viewModelScope.launch {
            userRepository.updateUser(user)
        }
    }

    fun deleteUser(user: User) {
        viewModelScope.launch {
            userRepository.deleteUser(user)
        }
    }
}

در ViewModel، از MutableStateFlow برای نگهداری لیست کاربران استفاده می‌کنیم. همچنین، با استفاده از viewModelScope.launch و collect، می‌توانیم کدها را در یک کروتین اجرا کنیم و تغییرات را در _users منتشر کنیم.

استفاده از کروتین‌ها و Flow در کدهای MVVM باعث می‌شود عملیات بر روی دیتابیس به صورت غیرقطعی و به صورت همروند انجام شود. همچنین، با استفاده از Flow، می‌توانید تغییراتی که در دیتابیس رخ می‌دهد را به طور فعال دریافت کنید و رابط کاربری خود را به روز کنید.

آیا استفاده از کروتین‌ها و Flow در کدهای MVVM باعث افزایش عملکرد برنامه می‌شود؟

بله، استفاده از کروتین‌ها و Flow در کدهای MVVM می‌تواند بهبود و افزایش عملکرد برنامه شما را به همراه داشته باشد. دلایل اصلی عملکرد بهتر عبارتند از:

1. همروندی (Concurrency)

با استفاده از کروتین‌ها و Flow، می‌توانید عملیات‌های بلوک‌کننده را به صورت غیرقطعی و همروند اجرا کنید بدون تأثیر منفی بر روی رابط کاربری. این بدان معناست که می‌توانید عملیات شبکه، دسترسی به پایگاه داده و سایر عملیات‌های طولانی مدت را در کروتین‌ها اجرا کنید و به رویدادها و تغییرات در زمان واقعی پاسخ دهید.

2. کد کمتر و خوانا‌تر

استفاده از کروتین‌ها و Flow به شما امکان می‌دهد کدهای همروند را به صورت ساده‌تر و خوانا‌تر نوشته و مدیریت کنید. با استفاده از کلیدواژه suspend و توابع انتشاری (asFlow) می‌توانید کدهای همروند خود را به صورت معمولی نوشته و آنها را به سادگی به کروتین‌ها و Flow تبدیل کنید.

3. تطبیق بهتر با LiveData

Flow به عنوان یک جایگزین برای LiveData عمل می‌کند و قابلیت‌های بیشتری را ارائه می‌دهد. به طور معمول، می‌توانید یک Flow را به LiveData تبدیل کنید و از قابلیت‌های جدیدی مانند ترکیب Flow ها، توابع تبدیل و عملگرهای مربوط به Flow استفاده کنید. این به شما امکان می‌دهد تا با استفاده از Flow، مبانی و اصول برنامه‌نویسی ریئکتیو را بهبود بخشید و کدهایی را که بر پایه LiveData بودند، بهتر مدیریت کنید.

در کل، استفاده از کروتین‌ها و Flow در کدهای MVVM می‌تواند بهبود‌های قابل توجهی در عملکرد و کارایی برنامه شما به همراه داشته باشد، به خصوص در مورد عملیات‌های همروند و بلوک‌کننده.

و همچنین ممنون میشم از طریق ستاره‌های این پایین به این مقاله امتیاز بدی و اگه هر سوالی داشتی توی قسمت دیدگاه بپرس و قطعا بهت پاسخ میدیم.

‫5/5 ‫(1 نظر)
عاطفه امیری

View Comments

Recent Posts

چگونه دوره آموزشی کاتلین پیشرفته می‌تواند مهارت‌های شما را ارتقاء دهد؟

دوره آموزشی کاتلین پیشرفته می‌تواند مهارت‌های شما را با بهره‌گیری از ابزارها و فناوری‌های مدرن…

4 ماه ago

مزیت‌های کاتلین نسبت به سایر زبان‌های برنامه نویسی اندروید

مزیت‌های کاتلین نسبت به سایر زبان‌های برنامه نویسی اندروید این است که سایر زبان‌ها، از…

5 ماه ago

بهینه‌سازی عملکرد اپلیکیشن‌های اندروید: راهنمای جامع و کاربردی

بهینه‌سازی عملکرد اپلیکیشن‌های اندروید یکی از مهم‌ترین فاکتورهایی است که برای کاربران در دنیای امروز…

10 ماه ago

سوالات مصاحبه‌ی استخدامی کاتلین همراه با جواب(قسمت چهارم)

مصاحبه‌ی استخدامی کاتلین یک فرصت برای ارزیابی مهارت‌ها و توانایی‌های یک برنامه‌نویس در توسعه اپلیکیشن‌های…

11 ماه ago

سوالات مصاحبه استخدام زبان کاتلین همراه با جواب(قسمت سوم)

مصاحبه استخدام زبان کاتلین یک فرصت برای ارزیابی مهارت‌ها و توانایی‌های یک برنامه‌نویس در توسعه…

11 ماه ago

سوالات مصاحبه استخدام کاتلین همراه با جواب(قسمت دوم)

مصاحبه استخدام کاتلین یک فرصت برای ارزیابی مهارت‌ها و توانایی‌های یک برنامه‌نویس در توسعه اپلیکیشن‌های…

11 ماه ago