Room 是 Android Jetpack 中用来处理数据库的框架,它可以用来替代原有的 SQLiteOpenHelper,简化数据库操作。
Android Room with a View 是一个 Google Codelab 用来展示 Jetpack Room 用法的 app。它可以输入一个单词并自动刷新显示数据库中的所有单词。通过 Android Room with a View 这个项目可以熟悉 Android Jetpack 的 LiveData、ViewModel、Room 的用法。
Room 需要先新建一个 abstract 的 RoomDatabase 类,它继承自 RoomDatabase。
abstract class WordRoomDatabase : RoomDatabase() {
使用 @Database 注解表明使用 RoomDatabase 构造数据库。
@Database 注解有 2 个 方法:
- entities 表示数据库中有哪些表。通常用一个数据类表示表结构,比如 Word::class。
- version 表示当前数据库的版本号。数据库升级时会用到版本号。
@Database(entities = [Word::class], version = 1)
WordRoomDatabase 类有一个抽象方法,用来返回 Dao 类,比如 WordDao。WordDao 定义了数据的增删改查接口。
abstract class WordRoomDatabase : RoomDatabase() {
abstract fun wordDao(): WordDao
getDatabase 方法使用单例模式构造 WordRoomDatabase 的实例。
abstract class WordRoomDatabase : RoomDatabase() {
fun getDatabase(context: Context, scope: CoroutineScope): WordRoomDatabase {
return INSTANCE ?: synchronized(this) {
var instance = Room.databaseBuilder(
context.applicationContext,
WordRoomDatabase::class.java,
"word_database"
.fallbackToDestructiveMigration()
.addCallback(WordDatabaseCallback(scope))
.build()
INSTANCE = instance
instance
getDatabase 使用 Room.databaseBuilder 构造 database。databaseBuilder 可以传入一个 Callback,它可以在数据库的生命周期执行回调,比如 database 的 onCreate 执行数据库的初始化操作,插入几条数据。
class WordDatabaseCallback(private val scope: CoroutineScope) : RoomDatabase.Callback() {
override fun onCreate(db: SupportSQLiteDatabase) {
super.onCreate(db)
INSTANCE?.let { database ->
scope.launch(Dispatchers.IO) {
populateDatabase(database.wordDao())
完整的 WordRoomDatabase 代码如下:
@Database(entities = [Word::class], version = 1)
abstract class WordRoomDatabase : RoomDatabase() {
abstract fun wordDao(): WordDao
companion object {
@Volatile
private var INSTANCE: WordRoomDatabase? = null
fun getDatabase(context: Context, scope: CoroutineScope): WordRoomDatabase {
return INSTANCE ?: synchronized(this) {
var instance = Room.databaseBuilder(
context.applicationContext,
WordRoomDatabase::class.java,
"word_database"
.fallbackToDestructiveMigration()
.addCallback(WordDatabaseCallback(scope))
.build()
INSTANCE = instance
instance
class WordDatabaseCallback(private val scope: CoroutineScope) : RoomDatabase.Callback() {
override fun onCreate(db: SupportSQLiteDatabase) {
super.onCreate(db)
INSTANCE?.let { database ->
scope.launch(Dispatchers.IO) {
populateDatabase(database.wordDao())
suspend fun populateDatabase(wordDao: WordDao) {
wordDao.deleteAll()
var word = Word("Hello")
wordDao.insert(word)
word = Word("World!")
wordDao.insert(word)
LiveData 将数据转换为可以被观察的数据。当数据发生变化时,LiveData 会将变化传递给 LiveData 定义的观察者。
wordViewModel.allWords 是一个 LiveData,当 words 发生变化时通知 adapter 刷新 recyclerview。
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
wordViewModel.allWords.observe(this) { words ->
words.let {
adapter.submitList(it)
repository.allWords 是 wordDao 定义的 Flow 流,它以 Flow 异步流的形式返回 Word 列表。
asLiveData 方法将 Flow 转换为 LiveData。
class WordViewModel(private val repository: WordRepository) : ViewModel() {
val allWords: LiveData<List<Word>> = repository.allWords.asLiveData()
class WordRepository(private val wordDao: WordDao) {
val allWords: Flow<List<Word>> = wordDao.getAlphabetizeWords()
lifecycle-livedata-ktx 依赖库的 FlowLiveData.kt 文件定义了 asLiveData 扩展函数。它可以将 Flow 转换为 LiveData。当数据库发生变化时,Flow 可以实时更新,从而通知 LiveData 刷新界面。
fun <T> Flow<T>.asLiveData(
context: CoroutineContext = EmptyCoroutineContext,
timeoutInMs: Long = DEFAULT_TIMEOUT
): LiveData<T> = liveData(context, timeoutInMs) {
collect {
emit(it)
实际上 Flow 的构造过程定义在 room-ktx 依赖库的 CoroutinesRoom 类的 createFlow,它给数据库加上了观察者(observer)。
class CoroutinesRoom private constructor() {
@JvmStatic
fun <R> createFlow(
db: RoomDatabase,
inTransaction: Boolean,
tableNames: Array<String>,
callable: Callable<R>
): Flow<@JvmSuppressWildcards R> = flow {
WordDao 数据访问接口在查询时返回 Flow。
interface WordDao {
@Query("SELECT * FROM word_table ORDER BY word ASC")
fun getAlphabetizeWords(): Flow<List<Word>>
* ignore 如果有冲突就不插入
@Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun insert(word: Word)
@Query("DELETE FROM word_table")
suspend fun deleteAll()
最后在 WordViewModel 保存 LiveData。外部 Activity 通过 WordViewModel 操作数据。
class WordViewModel(private val repository: WordRepository) : ViewModel() {
val allWords: LiveData<List<Word>> = repository.allWords.asLiveData()
Codelab : Android Room with A View - Kotlin
googlecodelabs/android-room-with-a-view
Kotlin 数据流
Android Jetpack 之使用 Room 操作数据库Room 是 Android Jetpack 中用来处理数据库的框架,它可以用来替代原有的 SQLiteOpenHelper,简化数据库操作。Android Room with a View 是一个 Google Codelab 用来展示 Jetpack Room 用法的 app。它可以输入一个单词并自动刷新显示数据库中的所有单词。通过 Android Room with a View 这个项目可以熟悉 Android Jetpack 的 Li
Android Jetpack架构组件-Room基本使用
Android Jetpack架构组件-Room数据库查询艺术
Android Jetpack架构组件-Room升级
在Android中使用任何一种数据库框架,少不了应用的迭代和数据库的升级,那么Room的该如何正确的升级?
一、Room数据库升级
第一步:增加version数据,及版本号增加
@Database(entities = [Cheese::class, User::class], version = 2, exportSchema = true)
abstract class CheeseDb :
使用 Room 库存储应用数据时,通过定义数据访问对象(DAOs)与存储的数据进行交互。每一个 DAO 包含用来访问应用数据库的抽象方法,在编译时, Room 会自动生成并实现在 DAO 中定义的访问方法
另外,本文本还介绍了 DAO 异步查询的相关内容,为了防止数据查询操作阻断 UI,造成 UI 卡顿,Room 不允许在 UI 主线程中访问数据库。这就意味着开发者必须将 DAO 中的查询定义成异步的。Room 库包含与多阿哥不同的框架进行集成,提供异步查询支持。
一.Room简介
Room是Google推出的数据库框架,是一个 ORM (Object Relational Mapping)对象关系映射数据库、其底层还是对SQLite的封装。 使用ORM可以让开发者更加关注业务逻辑,而不是SQL 语句。在JavaWeb领域也有类似的ORM 数据库框架Hibernate、MyBatis等等。
1.Android平台数据库框架
在 Android 中常见的数据库框架:
Greendao
Realm
DBFlow
LitePal
Jetpack-Room
相关文章:
Jetpack:Room超详细使用踩坑指南!
Jetpack:Room+kotlin协程? 事务问题分析,withTransaction API 详解.
Room在搭建的时候出现几个小问题,记录一下。基本都是配置问题:
There is a problem with the query: [SQLITE_ERROR] SQL error or missing database (no such table: simple_student)。
编译的时候报错,找不到表。
需要在声明
def room_version = "2.3.0"
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"
// 可选 - RxJava2 suppor
安卓
jetpack 的
room数据库框架是基于Sqlite3的
数据库,但是有别于sqlite,因此
使用查看sqlite的
数据库可视化软件看不到
room的
数据库的值(但是可以打开),
使用Androidstudio自带的databaseinspector,高版本的AS需要在APP inspection里面打开,另外应用必须是debug版本
Room 是 Google 官方推出的数据库 **ORM 框架**。ORM:即 Object Relational Mapping,即对象关系映射,也就是将关系型数据库映射为面向对象的语言。使用 ORM 框架,我们就可以用面向对象的思想操作关系型数据库,不再需要编写 SQL 语句。
Room 是在 **SQLite** 的基础上提供了一个抽象层,以便在充分利用 SQLite 的强大功能的同时,能够更简便的访问数据库。