Android使用Jetpack Room管理数据库 – 第二弹

Jetpack Room是Android官方提供的一个持久化库,旨在简化Android应用程序中的数据库操作。它提供了一个抽象层,使开发人员能够以面向对象的方式处理数据库操作,而无需编写复杂的SQL查询语句。通过使用Jetpack Room,开发人员可以更快速、更高效地构建稳健的数据库驱动应用程序。

Room 最新版本为2.5.2

Android Studio版本为 Android Studio Flamingo | 2022.2.1 Patch 2

Android使用Jetpack Room管理数据库 – 第一弹

Android使用Jetpack Room管理数据库 – 第二弹

开篇

上一篇文章我们介绍了Room的入门使用和Entity的高阶用法,基本包含了日常开发所需的大部分知识,但是还缺少了一个重要的功能,那就是数据库的升级,在日常版本迭代中,升级数据库是避免不了的,下面我们进入Room升级功能中瞅一瞅。

新增字段

这里还是接着上一篇的UserEntity来继续介绍Room增加字段之后该如何处理,当我们为UserEntity添加age字段之后,此时如果不对Room做任何处理,那么在运行的过程中会产生Room cannot verify the data integrity. Looks like you've changed schema but forgot to update the version number. You can simply fix this by increasing the version number错误提示,它告诉我们在Room中要对新增的age字段做升级处理并且修改数据库的版本号。

下面我们先进行数据库版本号的升级

@Database(entities = [UserEntity::class], version = 2, exportSchema = false)
abstract class RoomDb : RoomDatabase() {




    abstract fun getUserDao(): UserDao



}

RoomDb的类注解中,将version字段+1,此时版本号变为2,仅修改这里还是不够,虽然数据库的版本号升级了,但是Room不知道age这个字段该如何处理,接下来我们通过Migration来进行字段的添加。

val addAge = object : Migration(1, 2) {
    override fun migrate(database: SupportSQLiteDatabase) {

        database.execSQL("ALTER TABLE user_entity add column age INTEGER NOT NULL DEFAULT 0")
    }

}


Migration专门为数据库升级提供服务,我们在migrate()方法中通过SQL语句新增了age字段,此SQL还是比较简单的,就是往user_entity数据表中添加age字段,标明是一个Int类型并且不可为空,默认值为0,以此类推String可设置为空字符串。migrate(startVersion, endVersion)前两个参数就是升级前的版本号和升级后的版本号,版本号千万不能写错,不然升级就会报错了。

处理完SQL之后,最后只需要配置给Room.databaseBuilder()即可。

single {
    Room.databaseBuilder(androidContext(), RoomDb::class.java, "room_db")
        .addMigrations(addAge)
        .build()
}


到这为止我们就完成了数据表新增字段的操作了,下面看下新增一条数据的效果

通过App Inspection就可以看到新增的age字段已经在表中了。

新增表

上面我们了解了如何向数据表中新增字段的操作,接下来我们看看如何新增一张全新的数据表操作。假设我们在需求中需要保存房间的信息,房间信息包含idname等字段,这时候我们就需要按照下面操作来进行新增表:

  • 定义房间数据类,并加上@Entity注解
  • 创建房间的Dao接口
  • RoomDatabase增加entity数据,并且修改版本号,增加获取HomeDao的抽象方法
  • 最后在Room.databaseBuilder()新增表结构

定义Home数据类

@Entity(tableName = "home_entity")
data class Home(
    @PrimaryKey
    val id: Int,
    val name: String
)

定义Home表结构字段、表名和主键

创建HomeDao接口

@Dao
interface HomeDao {



    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insertHome(home: Home)
}

创建HomeDao接口,别忘记@Dao注解哦,这里就定义一个插入方法来演示,其余修改、删除等操作这里就不再多说,第一篇已经介绍过。

修改RoomDatabase

@Database(entities = [UserEntity::class, Home::class], version = 3, exportSchema = false)
abstract class RoomDb : RoomDatabase() {




    abstract fun getUserDao(): UserDao



    abstract fun getHomeDao(): HomeDao
}

这里修改点有三处,首先要将Home添加Daoentities数组中,然后将version字段+1,最后新增getHomeDao()抽象方法,Room会字段为我们实现此方法的具体逻辑。

新增Home表

我们需要先定义migrate来告诉Room新增的home_entity表结构,然后通过addMigrations操作来让Room执行数据表的新增。

val addHomeEntity = object : Migration(2, 3) {
    override fun migrate(database: SupportSQLiteDatabase) {

        database.execSQL("CREATE TABLE IF NOT EXISTS `home_entity` (`id` INTEGER NOT NULL, `name` TEXT NOT NULL, PRIMARY KEY(`id`))")
    }

}



Room.databaseBuilder(androidContext(), RoomDb::class.java, "room_db")
    .addMigrations(addAge)
    .addMigrations(addHomeEntity)
    .build()

database.execSQL()的写法中有一个小技巧,对于字段少的表来说我们可以一个字段一个字段的写类型,如果新增的表结构非常复杂,此时我们可以先不着急写SQL语句,我们先reBuild下工程,然后在build/generated/source/kapt/debug/包名下找到RoomDb_Impl.java

图片标红的地方就是Room自动生成的SQL语句,我们只需要Copy一下,这样就帮助我们解决繁琐的语句了。

到这为止新增表的操作就全部完成了,接下来我们插入一条数据看看home_entity表数据。

依旧是通过App Inspection观察数据库,可以看到我们新增的home_entity表已经完成了,并且里面还有一条插入的数据。

结尾

数据库的升级就介绍完啦,日常开发中新增字段和新增表的操作都已经在上面阐述了,如果还有其它的问题,欢迎评论区一起讨论???

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYIbIp4n' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片