Jetpack組件Room簡單Demo

1.Room介紹

Room是處理數據庫的一箇中間件,光其自身就有很多組件和概念,這個demo主要用到entity,dao,database,repository

  • entity 實體,創建一個表格
  • dao 接口類,是一種數據訪問對象,使用dao從數據庫中獲取實體,訪問數據庫的一個interface,增刪改查都在這
  • database 抽象類,父類是RoomDataBase,主要是將entity和dao整合到這裏
  • repository 倉庫,訪問數據庫的都在這
  • migration 版本遷移
  • asyncTask 線程(主要在java中)

2.添加依賴

def room_version = "2.2.3"
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
implementation "androidx.room:room-ktx:$room_version"
testImplementation "androidx.room:room-testing:$room_version"

具體流程可以參考我的另一篇博客(如果添加後,不能buildOutput,一定去看一下),有完整的流程。

3.建表:Word類

package com.example.ngsl.room

import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey

//定義一張表
@Entity(tableName = "word_table")
data class Word constructor(
    @ColumnInfo(name = "english")
    var english: String? = null
) {
    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "id")
    var wordId: Long = 0
}

4.表的操作:WordDao接口類

package com.example.ngsl.room

import androidx.lifecycle.LiveData
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query

@Dao
interface WordDao {
	//插入數據
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertAll(word: List<Word>)

    //查詢全部數據
    @Query("SELECT * FROM word_table")
    fun selectAllValueFromWord(): LiveData<List<Word>>
}

5.定義數據庫:AppDatabase 抽象類

package com.example.ngsl.room

import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.sqlite.db.SupportSQLiteDatabase
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkManager
import com.example.ngsl.DATABASE_NAME

@Database(entities = [Word::class] , version = 1, exportSchema = false)
abstract class AppDatabase : RoomDatabase() {
	//定義Dao
    abstract fun wordDao(): WordDao

    companion object {
		//單例模式
        @Volatile private var instance: AppDatabase? = null
		//創建數據庫
        fun getInstance(context: Context): AppDatabase {
            return instance ?: synchronized(this) {
                instance ?: buildDatabase(context).also { instance = it }
            }
        }
        //這是創建數據庫時,往數據中導入數據,通過WorkManager實現
        private fun buildDatabase(context: Context): AppDatabase {
            return Room.databaseBuilder(context, AppDatabase::class.java, DATABASE_NAME)
                .addCallback(object : RoomDatabase.Callback() {
                    override fun onCreate(db: SupportSQLiteDatabase) {
                        super.onCreate(db)
                        val request = OneTimeWorkRequestBuilder<AppDatabaseWorker>().build()
                        WorkManager.getInstance(context).enqueue(request)
                    }
                })
                .build()
        }
    }
//創建數據庫時不需要導入數據,可以這麼寫,代替上面的
//    companion object {
//        @Volatile
//        private var instance: AppDatabase? = null
//
//        fun getInstance(context: Context): AppDatabase {
//            return instance ?: synchronized(this) {
//                instance ?: Room.databaseBuilder(
//                    context,
//                    AppDatabase::class.java,
//                    DATABASE_NAME
//                ).build().also { instance = it }
//            }
//        }
//    }
}

像往數據庫中導入大量數據時,交給WorkManager來做,會好很多,具體用法參考我的另一篇博客

6.定義訪問倉庫:WordRepository類

package com.example.ngsl.room

import android.content.Context

//數據庫相關的操作都應該放在這
class WordRepository private constructor(context: Context) {
	//訪問數據庫,創建一個Dao,用於操作表
    private val wordDao: WordDao by lazy {
        AppDatabase.getInstance(context).wordDao()
    }

    //獲取所有數據
    val allWord = wordDao.selectAllValueFromWord()

    //插入數據
    suspend fun insertAll(word: List<Word>) {
        wordDao.insertAll(word)
    }

    companion object {
        //單例模式:就是在任何地方聲明這個類,都會返回同一個對象
        @Volatile
        private var instance: WordRepository? = null

        fun getInstance(context: Context) =
            instance ?: synchronized(this) {
                instance ?: WordRepository(context).also { instance = it }
            }
    }
}

至此,room中間件的定義就完成了

7.訪問數據庫數據,這裏用ViewModel來訪問數據

package com.example.ngsl.wordFragment

import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import com.example.ngsl.room.Word
import com.example.ngsl.room.WordRepository

//注意,這裏繼承:AndroidViewModel
class WordViewModel(application: Application) : AndroidViewModel(application) {
    //allWord是WordViewModel管理的數據
    val allWord: LiveData<List<Word>>
    init {
        //repository倉庫
        val wordRepository = WordRepository.getInstance(application.applicationContext)
        //通過repository來進行所有數據庫相關操作,這裏是獲取所有的數據
        allWord = wordRepository.allWord
    }
}

8.GitHub源碼鏈接

整個項目有很多組件,只看你需要的部分:https://github.com/YDDUONG/NGSL-English
如果覺得有用,點個贊吧

發佈了92 篇原創文章 · 獲贊 40 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章