Jetpack系列之Room数据库|让你秒懂熟练掌握Room

Room介绍

  1. Room是一个OM(Object Mapping对象映射)数据库,可以方便地在Android应用程序上访问数据库。
  2. Room抽象了SQLite,通过提供方便的api来查询数据库,并在编译时验证。并且可以使用SQLite的全部功能,同时拥有Java SQL查询生成器提供的类型安全。

Room的构成

  1. Database:数据库扩展了RoomDatabase的抽象类。可以通过Room获得它的一个实例。databaseBuilder或Room.inMemoryDatabaseBuilder。
  2. Entity:代表一个表结构。
  3. Dao:数据访问对象是Room的主要组件,负责定义访问数据库的方法。

声明依赖项

     def room_version = "2.3.0"

     implementation "androidx.room:room-runtime:$room_version"

     annotationProcessor "androidx.room:room-compiler:$room_version"
    

配置编译器选项

配置编译器解释

  1. “room.schemaLocation”:"$projectDir/schemas".toString(),的作用是将配置并启把据库架构导出json文件到指定目录
  2. “room.incremental”:“true”:Gradle 增量注解处理器
  3. “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
    }
}

表注解解释

  1. 如果想给一个表设置表名就在@Entity的后面添加(tableName = “book”),不是设置默认采用类名
  2. 声明表的主键 @PrimaryKey(autoGenerate = true)
  3. 更改表的属性列名@ColumnInfo(name = “bookname”),默认类的字段名
    1. 定义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时返回值类型和查询的表名和返回值类型或查询的表名不相同时,在程序编译会编译失败,这也降低了程序在运行时出现的风险

    1. 定义数据库和生成数据类
@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
        }
     }
}

数据库升级

  1. addMigrations(Migration migrations…):一个迁移可以处理多个版本
  2. Migration(int startVersion, int endVersion):每次迁移都可以在定义的两个版本之间移动,初始版本和目标版本,
  3. 在重写的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()实体的外键约束列表
StringtableName()数据库表名,默认是类名
Index[]indices()索引列表
booleaninheritSuperIndices()如果设置为true,在该类的父类中定义的任何索引将被转移到当前实体
String[]ignoredColumns()忽略的列名列表
String[]primaryKeys()主键列名的列表

@Dao

注解名称参数类型作用
@Query()String查询sql
@DeleteClass删除一条对应的实体
@Insert参数1.Class 参数2.onConflict1.添加一条对应的实体类 2.发生冲突的是做法(共五种策略,默认是事务回滚)

@Database

注解名称参数类型作用
AutoMigration[]autoMigrations()可在此数据库上执行的自动迁移列表
Class[]<?>entities()数据库中包含的实体列表
booleanexportSchema()您可以设置注释处理程序参数(Room . schemalocation)来告诉Room将数据库模式导出到一个文件夹中
intversion()数据库版本
Class[]<?>views()数据库中包含的数据库视图列表。

总结

Room没有隐藏SQLite的细节,而是试图通过提供方便的api来查询数据库,并在编译时验证这些查询。这允许您访问SQLite的全部功能,同时拥有Java SQL查询生成器提供的类型安全

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于 Room 数据库的升级,您需要遵循以下步骤: 1. 在新版本的数据库中定义新表结构或对旧表结构进行更改,例如添加、删除或修改表的列。 2. 在您的 `AppDatabase` 类中增加数据库版本号,可以在类上使用 `@Database` 注解指定版本号,例如: ```kotlin @Database(entities = [User::class], version = 2) abstract class AppDatabase : RoomDatabase() { //... } ``` 3. 创建一个实现 `Migration` 接口的类,该类将包含从旧版本升级到新版本所需的所有更改。例如: ```kotlin val migration_1_2 = object : Migration(1, 2) { override fun migrate(database: SupportSQLiteDatabase) { database.execSQL("ALTER TABLE users ADD COLUMN age INTEGER NOT NULL DEFAULT 0") } } ``` 该示例代码表示,从版本 1 升级到版本 2,需要在 `users` 表中添加一个名为 `age` 的整数类型的列。 4. 在 `AppDatabase` 类中,使用 `addMigrations()` 方法将 `Migration` 对象添加到数据库中,例如: ```kotlin @Database(entities = [User::class], version = 2) abstract class AppDatabase : RoomDatabase() { //... companion object { val migration_1_2 = object : Migration(1, 2) { override fun migrate(database: SupportSQLiteDatabase) { database.execSQL("ALTER TABLE users ADD COLUMN age INTEGER NOT NULL DEFAULT 0") } } } //... init { if (BuildConfig.DEBUG) { // 在调试模式下,如果发现数据结构变化,将会清空数据 fallbackToDestructiveMigration() } else { // 在正式发布模式下,如果发现数据结构变化,将会执行升级脚本 addMigrations(migration_1_2) } } } ``` 在上述示例代码中,我们将 `migration_1_2` 对象添加到 `AppDatabase` 类的伴生对象中,并在 `init` 块中进行了初始化。我们还使用了 `fallbackToDestructiveMigration()` 方法,如果在调试模式下发现数据结构变化,将会清空数据。在正式发布模式下,我们使用了 `addMigrations()` 方法,将 `migration_1_2` 对象添加到数据库中,以执行升级脚本。 这样,在您的应用程序使用新版本的数据库时,将自动执行升级脚本,以将旧数据结构转换为新数据结构。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值