Room是对sqlite的封装,让开发者可以更加效率的使用数据持久化保存。
一、使用方法
room_version = "2.1.0-rc01"
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
1、定义Entity数据类
默认表名为User,关键字为id,其他字段有nickName
@Entity
data class User (
@PrimaryKey var id: Long,
var nickName: String
)
也可以重新定义表名,多个关键字的定义,多个外键的定义,定义不为表字段的属性
@Entity(tableName="", primaryKeys = [], foreignKeys = [], ignoredColumns = [])
data class User (
@PrimaryKey var id: Long,
var nickName: String
)
更多定义可以查看相关注解
2、定义Dao接口类
@Dao
interface UserDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(user: User): Completable
@Query("SELECT * FROM user WHERE id = :userId")
fun query(userId: Long): Flowable<User>
@Query("SELECT * FROM user WHERE id in (:array)")
fun querySome(array: List<String>): Flowable<List<User>>
}
该接口类定义了相关数据类Entity的操作函数,具体实现是由注解来做的,而我们仅需要定义就可以了,节约了很多时间,也为不熟悉数据库操作的同学提供便捷的实现方法。
3、定义Database
@Database(entities = [User::class], version = 1, exportSchema = false)
abstract class MyRoomDatabase: RoomDatabase() {
abstract fun userDao(): UserDao
companion object {
@Volatile private var INSTANCE: MyRoomDatabase? = null
fun getInstance(mContext: Context): MyRoomDatabase =
INSTANCE ?: synchronized(this) {
INSTANCE ?: buildDatabase(mContext).also { INSTANCE = it }
}
private fun buildDatabase(mContext: Context) =
Room.databaseBuilder(mContext, MyRoomDatabase::class.java, "xxx.db")
// 数据库升级等时需要添加该方法
.addMigrations(object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
// 数据库升级等
}
})
.build()
}
}
这个类主要是用来创建数据库文件、版本管理、接口引用的,同样会由注解做相关的实现。
Database注解可以配置四个属性:entities、views、version、exportSchema
entities:指的是Entity类集合
views:是DatabaseView集合
version:数据库版本
exportSchema:是否导出数据库配置文件,true则需要配置导出路径,否则异常
defaultConfig {
javaCompileOptions {
annotationProcessorOptions {
arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
}
}
}
4、使用
使用方法很简单,拿到接口引用,然后调用接口方法就行了。
MyRoomDatabase.getInstance(mContext)
.userDao()
.query(1)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread()).
subscribe({}, {})
二、RxJava2
implementation "androidx.room:room-rxjava2:$room_version"
在定义Dao接口时,我们使用到了RxJava2的Completable和Flowable作为数据库操作的返回,因为数据库操作是不能放在UI线程的,所以这里应该使用异步,但是结果要显示又需要在UI线程,所以RxJava2是很不错的一个能很好实现异步且结果回归主线程的第三方库。
三、WorkerThread
数据库操作不能在UI线程,所以办法是在非UI线程去执行,然后在UI线程中刷新UI。