Room 在 SQLite 上提供了一个抽象层,以便在充分利用 SQLite 的强大功能的同时,能够流畅地访问数据库。
处理大量结构化数据的应用可极大地受益于在本地保留这些数据。最常见的用例是缓存相关数据。这样,当设备无法访问网络时,用户仍可在离线状态下浏览相应内容。设备重新连接到网络后,用户发起的所有内容更改都会同步到服务器。
由于 Room 负责处理这些问题,因此建议使用 Room(而不是 SQLite)
Room添加依赖如下:
implementation "androidx.room:room-runtime:$room_version" annotationProcessor "androidx.room:room-compiler:$room_version" // Kotlin使用kapt implementation "androidx.room:room-ktx:$room_version" // Room的kotlin扩展 implementation "androidx.room:room-rxjava2:$room_version"// Room的RxJava扩展
Room的架构由以下(注解)组成:
数据库(@DataBase)
:包含数据库持有者,并作为应用已保留的持久关系型数据的底层连接的主要接入点。使用 @Database 注释的类应满足以下条件:实体(@Entity)
:表示数据库中的表。 @Entity
data class User(
@PrimaryKey val uid: Int,
@ColumnInfo(name = "first_name") val firstName: String?,
@ColumnInfo(name = "last_name") val lastName: String?
)
创建了User表,@Entity表示为表Class,@PrimaryKey表示该属性为主键,@ColumnInfo表示当前行,name指明行名。
UserDao
@Dao
interface UserDao {
@Query("SELECT * FROM user")
fun getAll(): List<User>
@Query("SELECT * FROM user WHERE uid IN (:userIds)")
fun loadAllByIds(userIds: IntArray): List<User>
@Query("SELECT * FROM user WHERE first_name LIKE :first AND " +
"last_name LIKE :last LIMIT 1")
fun findByName(first: String, last: String): User
@Insert
fun insertAll(vararg users: User)
@Delete
fun delete(user: User)
}
@Dao注解表示对外暴露的数据库接口。
接口中函数的注解@Query执行查询操作,value写SQL 查询语句,SQL语法字符串采用大写,变量采用小写,”:“引用函数的参数,返回值根据结果而定,可返回LiveData或者配合RxJava扩展返回可订阅对象(Flowable, Maybe, Single, Completable),后面的@Insert,@Delete,@Update都一样。
AppDatabase
@Database(entities = arrayOf(User::class), version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
}
@Database表示数据库,里面的entities参数可指定表的Class,version指定版本号,等等,其他的可自行查看源码。
抽象类内部则是返回Dao的抽象方法。
最后创建数据库即可。
val db = Room.databaseBuilder(
applicationContext,
AppDatabase::class.java, "database-name"
).build()
以上编译完成后,会生成UserDao_Impl文件,顾名思义便是UserDao接口的实现。
当然这只是最简单的用法,你也可以结合LiveData和Rxjava实现响应式的获取数据。
@Query("SELECT * FROM user WHERE uid IN (:userIds)")
fun loadAllByIds(userIds: IntArray): LiveData<List<User>>
当数据库初始化或数据发生改变的时候会响应上面的方法,剩下的就是LiveData相关了,具体的操作可以了解下LiveData的使用方式。
与Rxjava配合比LiveData稍麻烦,但也无妨。
引入依赖:
implementation “androidx.room:room-rxjava2:$room_version”// Room的RxJava扩展
然后更改返回结果的类型:
@Query("SELECT * FROM user WHERE uid IN (:userIds)")
fun loadAllByIds(userIds: IntArray): Flowable<List<User>>
当然不只有Flowable一个返回类型,有以下几个:
onNext
和onError
也不会回调onNext
onNext
onComplete
onSuccess
和onComplete
onComplete
回调后如果数据发生更新,将不会响应onError(EmptyResultSetException.class)
onSuccess
onComplete
回调后如果数据发生更新,将不会响应所有根据实际的场景选择合适的方法才是正确的使用方式。