در این آموزش می خواهیم دیتابیس Room را توضیح دهیم. خب کمی در مورد دیتابیس room صحبت کنیم.
سورس کد این آموزش را میتوانید از اینجا دانلود کنید.
Room چیست؟
کتابخانه Room یک لایه abstraction است که بر روی SQLite قرارگرفته است.
دیتابیس Room یک ORM (Object Relational Mapper) برای پایگاه داده SQLite در اندروید است. دیتابیس Room با پیاده سازی annotation ها استفاده از SQLite را بسیار آسان کرده است.
چرا باید از دیتابیس Room استفاده کنیم؟
Compile Time Verification
در دیتابیس SQLite اگر query خطایی داشته باشد باعث ایجاد exception در زمان اجرا می شود. اگر از دیتابیس Room استفاده کنیم query را در زمان کامپایل بررسی می کند. بنابراین ما می توانیم از exception های زمان اجرا جلوگیری کنیم.
Boilerplate Code
برای تبدیل داده ها از SQLite به DTO (Data Transfer Object) باید کدهای زیادی بنویسیم. داده هایی که به صورت داخلی توسط Room مدیریت می شوند نیازی به نوشتن کد تبدیل ندارند.
به راحتی با دیگر Component های معماری ادغام میشود.
دیتابیس Room جزئی از Android Architecture است. بنابراین می تواند داده ها را بصورت observable مانند LiveData یا RxJava فراهم کند.
3 component اصلی در دیتابیس Room وجود دارد.
- Database
- Dao
- Entity
معماری دیتابیسRoom
Entity
- جدول موجود در پایگاه داده را نشان می دهد. Room برای هر کلاس جدولی ایجاد می کند وبا annotation های entity نوشته میشوند فیلدهای کلاس ستون های جدول را مشخص میکنند. بنابراین کلاسهای entity کلاسهای Model های کوچکی هستند که هیچ منطقی ندارند.
- برخی از annotation های مفید و ویژگی های آنها:
__ Foreign keys: نام کلیدهای خارجی
__ Indices: لیست نشانگرهای موجود در جدول
__ Primary keys : نام کلیدهای اصلی entity
__ table name : نام جدول
Primary Key این annotation کلید اصلی entity را نشان می دهد. AutoGenerate - اگر روی true تنظیم شود ، sqlite یک unique id برای ستون ایجاد می کند.
PrimaryKey(autoGenerate = true )
ColumnInfo امکان تعیین اطلاعات سفارشی در مورد ستون را فراهم می کند.
ColumnInfo(name = “column_name”)
Ignore فیلد توسط Room ادامه نخواهد یافت.
Database
برای ایجاد یک دیتابیس در Room باید یک کلاس ایجاد کنیم و آن را با یک annotation ,database مشخص میکنم ( @Database). در ورودی annotation باید نام جدول ها و نسخه دیتابیس را وارد کنیم.
مثال: @Database(entities = [Note::class], version = 1)
Dao
برای دسترسی به محتوای دیتابیس باید شی using را با استفاده از یک interface که حاوی انوتیشن Dao است را ایجاد کنیم. در داخل این interface ما باید متد های مورد نیاز برای عملیات db را ایجاد کنیم.
در اینجا می توانیم از 4 انوتیشن استفاده کنیم:
- Query
- Insert
- Update
- Delete
Qury : برای اجرای query خام ما باید از این انوتیشن استفاده کنیم.
Insert : با این انوتیشن میتوانید داده ها را در دیتابیس وارد کنید.
Update : با استفاده از این انوتیشن عملیات به روز رسانی روی داده های موجود در دیتابیس را انجام میدهید.
Delete : با این انوتیشن میتوانید داده ها را از روی دیتابیس پاک کنید.
چرا دیتابیس Room از طریق دیتابیس SQLite؟
- در زمان کامپایل query های Sql را تایید میکنید بنابراین زمان اجرا با خطاهای syntax مواجه نمیشوید.
- کد بسیار کمتری برای نوشتن.
- پشتیبانی از اداغام با Architecture Component
حال دیتابیس Room را با یک مثال پیاده سازی میکنیم.
مرحله 1: یک پروژه جدید در Android Studio با empty activity ایجاد کنید.
مرحله 2: وابستگی های زیر را اضافه کنید.
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.bugeto.todolist"
minSdkVersion 19
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
def lifecycle_version = "2.1.0"
def room_version = "2.2.3"
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'com.google.android.material:material:1.2.0-alpha03'
implementation 'androidx.core:core-ktx:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
// ViewModel and LiveData
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
kapt "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
implementation 'io.reactivex.rxjava2:rxjava:2.2.16'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}
مرحله 3: حالا بیایید یک Entity ایجاد کنیم.
- باید یک فیلد را به عنوان کلید اصلی اعلام کنید. این فیلد را با انوتیشن PrimaryKey و autoGenerate مشخص بنویسید که مقدار پیش فرض آن false است.
- کلاس با انوتیشن Entity مشخص شده و مقدار آن هم نامی است که برای جدول انتخاب شده است.
package com.bugeto.todolist
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "note_table")
data class Note(val title: String,
val description: String,
val priority: Int,
@PrimaryKey(autoGenerate = false) val id: Int? = null)
مرحله 4: با استفاده از interface یک Dao (Data access object) ایجاد کنید.
- این کلاس با انوتیشن Dao نوشته می شود.
- برای انجام عملیات CRUD چهار انوتیشن Query ، Insert ، Update ، Delete وجود دارد.
package com.bugeto.todolist
import androidx.lifecycle.LiveData
import androidx.room.*
@Dao
interface NoteDao {
@Insert
fun insert(note: Note)
@Update
fun update(note: Note)
@Delete
fun delete(note: Note)
@Query("delete from note_table")
fun deleteAllNotes()
@Query("select * from note_table order by priority desc")
fun getAllNotes(): LiveData<List<Note>>
}
مرحله 5: یک کلاس دیتابیس ایجاد کنید.کلاسNoteDatabase که از RoomDatabase مشتق میشود.
package com.bugeto.todolist
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.sqlite.db.SupportSQLiteDatabase
import com.huawei.todolist.utils.subscribeOnBackground
@Database(entities = [Note::class], version = 1)
abstract class NoteDatabase : RoomDatabase() {
abstract fun noteDao(): NoteDao
companion object {
private var instance: NoteDatabase? = null
@Synchronized
fun getInstance(ctx: Context): NoteDatabase {
if(instance == null)
instance = Room.databaseBuilder(ctx.applicationContext, NoteDatabase::class.java,
"note_database")
.fallbackToDestructiveMigration()
.addCallback(roomCallback)
.build()
return instance!!
}
private val roomCallback = object : Callback() {
override fun onCreate(db: SupportSQLiteDatabase) {
super.onCreate(db)
populateDatabase(instance!!)
}
}
private fun populateDatabase(db: NoteDatabase) {
val noteDao = db.noteDao()
subscribeOnBackground {
noteDao.insert(Note("title 1", "desc 1", 1))
noteDao.insert(Note("title 2", "desc 2", 2))
noteDao.insert(Note("title 3", "desc 3", 3))
}
}
}
}
مرحله 6: مدیریت داده ها
Query :
init {
noteDao = database.noteDao()
allNotes = noteDao.getAllNotes()
}
Insert :
fun insert(note: Note) {
subscribeOnBackground {
noteDao.insert(note)
}
}
Update :
fun update(note: Note) {
subscribeOnBackground {
noteDao.update(note)
}
}
Delete :
fun delete(note: Note) {
subscribeOnBackground {
noteDao.delete(note)
}
}
این آموزش هم به پایان رسید امیدوارم که مفید واقع شده باشد.
سوالات و مشکلات خود را در مورد با دیتابیس room در قسمت کامنت ها مطرح کنید تا به آنها پاسخ بدهم.
برای افزودن دیدگاه خود، نیاز است ابتدا وارد حساب کاربریتان شوید