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字段做升级处理并且修改数据库的版本号。
下面我们先进行数据库版本号的升级
kotlin
@Database(entities = [UserEntity::class], version = 2, exportSchema = false)
abstract class RoomDb : RoomDatabase() {
abstract fun getUserDao(): UserDao
}
在RoomDb的类注解中,将version字段+1,此时版本号变为2,仅修改这里还是不够,虽然数据库的版本号升级了,但是Room不知道age这个字段该如何处理,接下来我们通过Migration来进行字段的添加。
kotlin
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()即可。
css
single {
Room.databaseBuilder(androidContext(), RoomDb::class.java, "room_db")
.addMigrations(addAge)
.build()
}
到这为止我们就完成了数据表新增字段的操作了,下面看下新增一条数据的效果

通过App Inspection就可以看到新增的age字段已经在表中了。
新增表
上面我们了解了如何向数据表中新增字段的操作,接下来我们看看如何新增一张全新的数据表操作。假设我们在需求中需要保存房间的信息,房间信息包含id和name等字段,这时候我们就需要按照下面操作来进行新增表:
- 定义房间数据类,并加上
@Entity注解 - 创建房间的
Dao接口 - 在
RoomDatabase增加entity数据,并且修改版本号,增加获取HomeDao的抽象方法 - 最后在
Room.databaseBuilder()新增表结构
定义Home数据类
less
@Entity(tableName = "home_entity")
data class Home(
@PrimaryKey
val id: Int,
val name: String
)
定义Home表结构字段、表名和主键
创建HomeDao接口
kotlin
@Dao
interface HomeDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertHome(home: Home)
}
创建HomeDao接口,别忘记@Dao注解哦,这里就定义一个插入方法来演示,其余修改、删除等操作这里就不再多说,第一篇已经介绍过。
修改RoomDatabase
kotlin
@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执行数据表的新增。
kotlin
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表已经完成了,并且里面还有一条插入的数据。
结尾
数据库的升级就介绍完啦,日常开发中新增字段和新增表的操作都已经在上面阐述了,如果还有其它的问题,欢迎评论区一起讨论🌹🌹🌹