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
如果覺得有用,點個贊吧