您现在的位置:首页 > >

Jetpack Room入门系列:(一)基本介绍

发布时间:


Android Jetpack的出现统一了Android开发生态,各种三方库逐渐被官方组件所取代。Room也同样如此,逐渐取代竞品成为最主流的数据库ORM框架。这当然不仅仅因为其官方身份,更是因为其良好的开发体验,大大降低了SQLite的使用门槛。


Jetpack Room入门系列:(一)基本介绍
Jetpack Room入门系列:(二)使用DAO读写数据库
Jetpack Room入门系列:(三)实体/数据表关系
Jetpack Room入门系列:(四)内部实现原理
Jetpack Room入门系列:(五)数据库版本升级、数据迁移
Jetpack Room入门系列:(六)配合LiveData等三方库的使用




框架特点

相对于SQLiteOpenHelper等传统方法,使用Room操作SQLite有以下优势:


编译期的SQL语法检查开发高效,避免大量模板代码API设计友好,容易理解可以与RxJavaLiveDataKotlin Coroutines等进行桥接


添加依赖

dependencies {
implementation "androidx.room:room-runtime:2.2.5"
kapt "androidx.room:room-compiler:2.2.5"
}



基本组件

Room的使用,主要涉及以下3个组件


Database: 访问底层数据库的入口Entity: 代表数据库中的表(table),一般用注解Data Access Object (DAO): 数据库访问者

这三个组件的概念也出现在其他ORM框架中,有过使用经验的同学理解起来并不困难: 通过Database获取DAO,然后通过DAO查询并获取entities,最终通过entities对数据库table中数据进行读写



Database

Database是我们访问底层数据库的入口,管理着真正的数据库文件。我们使用@Database定义一个Database类:


派生自RoomDatabase关联其内部数据库table对应的entities提供获取DAO的抽象方法,且不能有参数

@Database(entities = arrayOf(User::class), version = 1)
abstract class UserDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
}

运行时,我们可以通过Room.databaseBuilder()或者 Room.inMemoryDatabaseBuilder()获取Database实例


val db = Room.databaseBuilder(
applicationContext,
UserDatabase::class.java, "users-db"
).build()


创建Databsse的成本较高,推荐使用单例的Database,避免反复创建实例带来的开销





Entity

一个Entity代表数据库中的一张表(table)。我们使用@Entity定义一个Entiry类,类中的属性对应表中的Column


@Entity
data class User(
@PrimaryKey val uid: Int,
@ColumnInfo(name = "first_name") val firstName: String?,
@ColumnInfo(name = "last_name") val lastName: String?
)

所有的属性必须是public、或者有get、set方法属性中至少有一个主键,使用@PrimaryKey表示单个主键,也可以像下面这样定义多主键

@Entity(primaryKeys = arrayOf("firstName", "lastName"))

当主键值为null时,autoGenerate可以帮助自动生成键值

@PrimaryKey(autoGenerate = true) val uid : Int

默认情况下使用类名作为数据库table名,也可使用tableName指定

@Entity(tableName = "users")

Entity中的所有属性都会被持久化到数据库,除非使用@Ignore

@Ignore val picture: Bitmap?

可以使用indices指定数据库索引,unique设置其为唯一索引

@Entity(indices = arrayOf(Index(value = ["last_name", "address"])))

@Entity(indices = arrayOf(Index(value = ["first_name", "last_name"],
unique = true)))



Data Access Object (DAO)

DAO提供了访问DB的API,我们使用@Dao定义DAO类,使用@Query@Insert@Delete定义CRUD方法


@Dao
interface UserDao {
@Query("SELECT * FROM user")
fun getAll(): List

@Query("SELECT * FROM user WHERE uid IN (:userIds)")
fun loadAllByIds(userIds: IntArray): List

@Insert
fun insertAll(vararg users: User)

@Delete
fun delete(user: User)
}


DAO的方法调用都在当前线程进行,所以要避免在UI线程直接访问





Type Converters

有时,需要将自定义类型的数据持久化到DB,此时需要借助Converters进行转换


class Converters {
@TypeConverter
fun fromTimestamp(value: Long?): Date? {
return value?.let { Date(it) }
}

@TypeConverter
fun dateToTimestamp(date: Date?): Long? {
return date?.time?.toLong()
}
}

在声明Database时,指定此Converters


@Database(entities = arrayOf(User::class), version = 1)
@TypeConverters(Converters::class)
abstract class UserDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
}


热文推荐
猜你喜欢
友情链接: 医学资料大全 农林牧渔 幼儿教育心得 小学教育 中学 高中 职业教育 成人教育 大学资料 求职职场 职场文档 总结汇报