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

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

    در این آموزش می خواهیم  دیتابیس 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 وجود دارد.

    1. Database
    2. Dao
    3. 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 در قسمت کامنت ها مطرح کنید تا به آنها پاسخ بدهم.

     

     

     

     


    • نویسنده: میثم بابائی

    ارسال دیدگاه

    برای افزودن دیدگاه خود، نیاز است ابتدا وارد حساب کاربری‌تان شوید


    دیدگاه کاربران