Jetpack系列之Room数据库|让你秒懂熟练掌握Room
Room介绍Room是一个OM(Object Mapping对象映射)数据库,可以方便地在Android应用程序上访问数据库。Room抽象了SQLite,通过提供方便的api来查询数据库,并在编译时验证。并且可以使用SQLite的全部功能,同时拥有Java SQL查询生成器提供的类型安全。Room的构成Database:数据库扩展了RoomDatabase的抽象类。可以通过Room获得它的一个实例
·
Room介绍
- Room是一个OM(Object Mapping对象映射)数据库,可以方便地在Android应用程序上访问数据库。
- Room抽象了SQLite,通过提供方便的api来查询数据库,并在编译时验证。并且可以使用SQLite的全部功能,同时拥有Java SQL查询生成器提供的类型安全。
Room的构成
- Database:数据库扩展了RoomDatabase的抽象类。可以通过Room获得它的一个实例。databaseBuilder或Room.inMemoryDatabaseBuilder。
- Entity:代表一个表结构。
- Dao:数据访问对象是Room的主要组件,负责定义访问数据库的方法。
声明依赖项
def room_version = "2.3.0"
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"
配置编译器选项
配置编译器解释
- “room.schemaLocation”:"$projectDir/schemas".toString(),的作用是将配置并启把据库架构导出json文件到指定目录
- “room.incremental”:“true”:Gradle 增量注解处理器
- “room.expandProjection”:“true”:配置 Room 以重写查询,使其顶部星形投影在展开后仅包含 DAO 方法返回类型中定义的列。
//配置编译器代码
android {
...
defaultConfig {
...
javaCompileOptions {
annotationProcessorOptions {
arguments += [
"room.schemaLocation":"$projectDir/schemas".toString(),
"room.incremental":"true",
"room.expandProjection":"true"]
}
}
}
}
定义数据表
创建图书表
@Entity(tableName = "book")
class Book {
@PrimaryKey(autoGenerate = true)
var id: Int = 0
@ColumnInfo(name = "bookname")
var name: String? = ""
constructor(bookname: String?) {
this.name = bookname
}
}
表注解解释
- 如果想给一个表设置表名就在@Entity的后面添加(tableName = “book”),不是设置默认采用类名
- 声明表的主键 @PrimaryKey(autoGenerate = true)
- 更改表的属性列名@ColumnInfo(name = “bookname”),默认类的字段名
-
- 定义Dao类
@Dao
interface BookDao {
@Insert
fun addBook(book : Book)
@Query("SELECT * FROM book")
fun loadAll(): List<Book?>?
@Query("select * from book where name = :name")
fun queryName(name : String) :List<Book?>?
@Delete
fun delete(song: Book?)
}
如果在query时返回值类型和查询的表名和返回值类型或查询的表名不相同时,在程序编译会编译失败,这也降低了程序在运行时出现的风险
-
- 定义数据库和生成数据类
@Database(entities = [Book::class], version = 1)
abstract class RoomDaoManager : RoomDatabase() {
abstract fun BookDao(): BookDao
companion object {
private val DATABASE_NAME = "dev_db.db"
private var databaseInstance: RoomDaoManager? = null
@Synchronized
open fun getInstance(): RoomDaoManager? {
if (databaseInstance == null) {
databaseInstance = Room
.databaseBuilder(
MyApplication.instance(),
RoomDaoManager::class.java,
DATABASE_NAME
)
.allowMainThreadQueries()
.build()
}
return databaseInstance
}
}
}
数据库升级
- addMigrations(Migration migrations…):一个迁移可以处理多个版本
- Migration(int startVersion, int endVersion):每次迁移都可以在定义的两个版本之间移动,初始版本和目标版本,
- 在重写的migrate方法中执行更新的sql,同时需要在对应的Entity类中添加相同的字段,来保证字段相同
Room .databaseBuilder(
MyApplication.instance(),
RoomDaoManager::class.java,
DATABASE_NAME
)
.allowMainThreadQueries()
.addMigrations(MIGRATION_1_2)
.build()
###addMigrations(Migration migrations...):一个迁移可以处理多个版本
###Migration:每次迁移都可以在定义的两个版本之间移动
val MIGRATION_1_2 = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
//对表增加一个字段
database.execSQL("ALTER TABLE Book ADD COLUMN sn TEXT NOT NULL DEFAULT ''")
}
}
LiveData和Room配合使用
//Livedata依赖
def lifecycle_version = "2.2.0"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
//返回值使用Livedata
@Query("SELECT * FROM book where id = :id")
fun queryLiveData(id : Int): LiveData<Book?>?
//通dao对象调用查询的方法
bookDao?.queryLiveData(1)?.observe(this, Observer {
Log.i("book-query","${it?.name}")
})
Rxjava和Room配合使用
//Rxjava2和Rxjava3 可以选择使用
def room_version = "2.3.0"
// optional - RxJava2 support for Room
implementation "androidx.room:room-rxjava2:$room_version"
// optional - RxJava3 support for Room
implementation "androidx.room:room-rxjava3:$room_version"
//定义使用Rxjava的方法
@Query("SELECT * FROM book where id = :id")
fun queryFlowable(id : Int): Flowable<Book?>?
Room数据库注解
@Entity
返回值 | 方法名 | 作用 |
---|---|---|
ForeignKey[] | foreignKeys() | 实体的外键约束列表 |
String | tableName() | 数据库表名,默认是类名 |
Index[] | indices() | 索引列表 |
boolean | inheritSuperIndices() | 如果设置为true,在该类的父类中定义的任何索引将被转移到当前实体 |
String[] | ignoredColumns() | 忽略的列名列表 |
String[] | primaryKeys() | 主键列名的列表 |
@Dao
注解名称 | 参数类型 | 作用 |
---|---|---|
@Query() | String | 查询sql |
@Delete | Class | 删除一条对应的实体 |
@Insert | 参数1.Class 参数2.onConflict | 1.添加一条对应的实体类 2.发生冲突的是做法(共五种策略,默认是事务回滚) |
@Database
注解名称 | 参数类型 | 作用 |
---|---|---|
AutoMigration[] | autoMigrations() | 可在此数据库上执行的自动迁移列表 |
Class[]<?> | entities() | 数据库中包含的实体列表 |
boolean | exportSchema() | 您可以设置注释处理程序参数(Room . schemalocation)来告诉Room将数据库模式导出到一个文件夹中 |
int | version() | 数据库版本 |
Class[]<?> | views() | 数据库中包含的数据库视图列表。 |
总结
Room没有隐藏SQLite的细节,而是试图通过提供方便的api来查询数据库,并在编译时验证这些查询。这允许您访问SQLite的全部功能,同时拥有Java SQL查询生成器提供的类型安全
更多推荐
已为社区贡献1条内容
所有评论(0)