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
如果觉得有用,点个赞吧