一、Room介绍

Android采用Sqlite作为数据库存储。Sqlite代码写起来繁琐且容易出错,所以开源社区里逐渐出现了各种ORM(Object Relational Mapping)库。这些开源ORM库都是为了方便Sqlite的使用,包括数据库的创建,升级,增删改查等。常见的ORM有ORMLite,GreenDAO等。Google也意识到了推出自家ORM的必要性,于是有了Room。

二、Room的使用

  • 导入依赖
def room_version = "2.4.2"
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"
  • 新建一个Entity
package com.example.jetpacktest

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

@Entity(tableName = "Word") //对应的是数据库中的表名称
class Word() {

//主键,自增
@PrimaryKey(autoGenerate = true)
var id: Int = 0

//不使用ColumnInfo,则使用字段名。这里name的值就是数据表的字段名。
@ColumnInfo(name = "english_word")
var word: String = ""

@ColumnInfo(name = "chinese_meaning")
var chineseMeaning: String = ""

override fun toString(): String {
return "Word(id=$id, word='$word', chineseMeaning='$chineseMeaning')"
}

constructor(_word: String, _chineseMeaning: String) : this() {
word = _word
chineseMeaning = _chineseMeaning
}
}
  • 操作数据表的接口Dao
package com.example.jetpacktest

import androidx.room.*

@Dao
interface WordDao {
@Insert
fun insertWords(vararg item: Word)

@Update
fun updateWords(vararg item: Word)

@Delete
fun deleteWords(vararg item: Word)

@Query("DELETE FROM Word")
fun deleteAllWords()

@Query("SELECT * FROM Word ORDER BY id DESC")
fun getAllWords(): List<Word>

}
  • 数据库名称,版本号等
package com.example.jetpacktest

import androidx.room.Database
import androidx.room.RoomDatabase

//entities: 实例类 version: 数据库版本号 exportSchema: 是否需要导出 Schema
@Database(entities = [Word::class], version = 1, exportSchema = false)
abstract class WordDataBase : RoomDatabase() {

abstract fun getWordDao(): WordDao

}
  • 在Activity中使用
  • Android-Room要求数据操作不能在UI线程中,需要在子线程中进行操作,因此使用kotlin的协程方式进行调用:
  • 使用协程首先添加依赖:
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.2'
package com.example.jetpacktest

import android.os.Bundle
import android.view.View
import androidx.annotation.RestrictTo
import androidx.appcompat.app.AppCompatActivity
import androidx.room.Room
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch

class MainActivity : AppCompatActivity() {

private var mWordDao: WordDao? = null

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

CoroutineScope(Dispatchers.IO).launch {
//这里的name表示 DataBase 名字
val mWordDataBase: WordDataBase =
Room.databaseBuilder(this@MainActivity, WordDataBase::class.java, "111").build()

mWordDao = mWordDataBase.getWordDao()
}

}

fun addData(view: View) {
//注意得开启一个协成使用,因为这是耗时操作,不能在主线程(UI线程做)
CoroutineScope(Dispatchers.IO).launch {
val word1 = Word("Hello", "你好")
val word2 = Word("World", "世界")
mWordDao?.insertWords(word1, word2)
println(mWordDao?.getAllWords())
}
}

fun updateData(view: View) {
CoroutineScope(Dispatchers.IO).launch {
val word = Word("hai", "你好啊")
word.id = 2
//如果id为2的数据不存在,则这条语句无反应
mWordDao?.updateWords(word)
println(mWordDao?.getAllWords())
}
}

fun deleteData(view: View) {
CoroutineScope(Dispatchers.IO).launch {
val word = Word("hai", "你好啊")
word.id = 2
//如果id为2的数据不存在,则这条语句无反应
mWordDao?.deleteWords(word)
println(mWordDao?.getAllWords())
}
}

fun clearData(view: View) {
CoroutineScope(Dispatchers.IO).launch {
mWordDao?.deleteAllWords()
println(mWordDao?.getAllWords())
}
}
}

三、效果展示

android room史上最快速入门教程(kotlin版本)_android

四、常见问题 

  • gradle导入依赖问题,半天依赖下载失败

android room史上最快速入门教程(kotlin版本)_maven_02

maven{ url 'https://maven.aliyun.com/repository/central'} 
maven{ url 'https://maven.aliyun.com/repository/public' }
maven{ url 'https://maven.aliyun.com/repository/google' }
maven{ url 'https://maven.aliyun.com/repository/gradle-plugin' }
maven{ url 'https://maven.aliyun.com/repository/spring' }
maven{ url 'https://maven.aliyun.com/repository/spring-plugin' }
maven{ url 'https://maven.aliyun.com/repository/grails-core' }
maven{ url 'https://maven.aliyun.com/repository/apache-snapshots' }
  • Caused by: java.lang.RuntimeException: cannot find implementation for com.examplexxx.xxxDataBase. xxxDataBase_Impl does not exist

       这个问题是注解处理器导入的问题

       解决办法如下

android room史上最快速入门教程(kotlin版本)_kotlin_03

  • Entities and POJOs must have a usable public constructor. You can have an empty constructor or a constructor whose parameters match the fields (by name and type).

        这个问题是 Entity 没有编写无参构造方法的问题

        解决方法如下:

Entity 添加一个无参构造方法即可

android room史上最快速入门教程(kotlin版本)_sqlite_04