文章目录
- 项目添加ksp插件
- 添加 room 引用
- 开始使用room
- 1. 创建bean
- 2. 创建 dao类
- 3. 创建database类
- 数据库升级
- 复制数据库到指定路径
- 参考文献
项目添加ksp插件
注意,因为ksp插件 是跟项目中使用的kotlin的版本要保持一致的,否则会报错的
- 首先我们去 https://github.com/google/ksp/releases 看一下目前的ksp 的版本是多少,我当时用的时候的版本是
2.0.0-1.0.22
,这里的版本数字代表的意思是kotlin的版本是2.0.0,ksp的版本是1.0.22
2. 我们打开项目的gradle/libs.versions.toml
文件,如下,我们看到我们使用的kotlin版本是1.9.0
,所以我们需要把kotlin的版本升级成2.0.0
注意: 如果我们在同步项目的时候发现报如下错误的时候,我们可以在
settings.gradle.kts
文件中配置阿里的maven
添加如下代码
pluginManagement {repositories {...maven { setUrl("https://maven.aliyun.com/nexus/content/groups/public/") }maven { setUrl("https://maven.aliyun.com/repository/gradle-plugin") }mavenCentral()gradlePluginPortal()}
}
dependencyResolutionManagement {...repositories {maven { setUrl("https://maven.aliyun.com/nexus/content/groups/public/") }google()mavenCentral()}
}
- 在项目的
build.gradle.kts
文件中添加引用,如下:plugins {alias(libs.plugins.androidApplication) apply falsealias(libs.plugins.jetbrainsKotlinAndroid) apply false// apply false 的意思是代表gradle 不会自动应用这个插件,性能优化id("com.google.devtools.ksp") version "2.0.0-1.0.22" apply false }
- 在模块的
build.gradle.kts
文件中添加如下代码。这样ksp插件就引入成功了plugins {...id("com.google.devtools.ksp") }
添加 room 引用
- 在app的
build.gradle.kts
文件中添加引用dependencies {...implementation("androidx.room:room-runtime:2.6.1")annotationProcessor("androidx.room:room-compiler:2.6.1")// To use Kotlin Symbol Processing (KSP)ksp("androidx.room:room-compiler:2.6.1")// optional - Kotlin Extensions and Coroutines support for Roomimplementation("androidx.room:room-ktx:2.6.1") }
在项目中你会遇到如下 黄色警告,可以点击下面的replace,它会自动的给你替换成使用
libs.versions.toml
的方式来引用
开始使用room
1. 创建bean
@Parcelize
@Entity(tableName = "person")
data class Person(@PrimaryKey(autoGenerate = true)var id: Long = 0,// 指定数据库表中列的名字,如果不指定就默认使用字段的名字@ColumnInfo(name = "name")var name: String = "",var gender: String = "",var telephone: String = "",var score: Int = 0,
) : Parcelable
2. 创建 dao类
@Dao
interface PersonDao {@Insert(onConflict = OnConflictStrategy.REPLACE)fun addPeople(person: Person)@Deletefun delPeople(person: Person)@Query("delete from person")fun delAll()@Updatefun update(person: Person)@Query("select * from person order by id asc")fun query(): List<Person>}
3. 创建database类
方式一
@Database(entities = [Person::class], version = 1, exportSchema = false)
abstract class MyDataBase : RoomDatabase() {abstract fun personDao(): PersonDao
}object DataBaseModule {fun getDb(context: Context) = Room.databaseBuilder(context = context,MyDataBase::class.java,"my_database")//允许在主线程中调用//.allowMainThreadQueries().build()}
方式二
@Database(entities = [Person::class], version = 2, exportSchema = false)
abstract class MyDataBase : RoomDatabase() {abstract fun personDao(): PersonDaocompanion object {@Volatileprivate var INSTANCE: MyDataBase? = nullfun getInstance(context: Context): MyDataBase? {return INSTANCE ?: synchronized(this) {val instance = Room.databaseBuilder(context.applicationContext,MyDataBase::class.java,"my_database")//允许在主线程中调用//.allowMainThreadQueries().build()INSTANCE = instanceINSTANCE}}}}
数据库升级
- 编写
Migration
类// 第一种 更新表结构 val MIGRATION_2_3 = object : Migration(2, 3) {override fun migrate(db: SupportSQLiteDatabase) {db.execSQL("ALTER TABLE person ADD COLUMN score INTEGER not null default 0")} }// 第二种 迁移数据 val MIGRATION_1_2 = object : Migration(1, 2) {override fun migrate(db: SupportSQLiteDatabase) {//1. 创建一个新表db.execSQL("""create table person_temp(id integer not null primary key autoincrement,name text not null ,gender text not null,telephone text not null,score integer not null default 0)""".trimIndent())//2. 迁移数据db.execSQL("""insert into person_temp(name,gender,telephone)select name,gender,telephone from person""".trimIndent())// 3. 删除旧表db.execSQL("drop table person")// 4. 重新命名新表db.execSQL("alter table person_temp rename to person")} }
- 在 database类中以
addMigrations
的方式添加进入object DataBaseModule {fun getDb(context: Context) = Room.databaseBuilder(context = context,MyDataBase::class.java,"my_database")//允许在主线程中调用//.allowMainThreadQueries().addMigrations(MIGRATION_1_2).addMigrations(MIGRATION_2_3).build()}
复制数据库到指定路径
CoroutineScope(Dispatchers.IO).launch {val writableDatabase = db.openHelper.writableDatabaseLog.e(TAG, "initListener: ${writableDatabase.path}")writableDatabase.path?.apply {// 获取数据库文件路径val dbFile = File(this)// 目标文件路径,你可以自定义路径和文件名val path = Environment.getExternalStorageDirectory().absolutePathLog.e(TAG, "initListener: $path")val targetFile = File(path, "copied_database.db")if (targetFile.exists()) {targetFile.delete()}targetFile.createNewFile()// 复制数据库文件try {Log.e(TAG, "initListener: 开始复制")val srcChannel: FileChannel = FileInputStream(dbFile).channelval dstChannel = FileOutputStream(targetFile).channeldstChannel.transferFrom(srcChannel, 0, srcChannel.size())srcChannel.close()dstChannel.close()Log.e(TAG, "initListener: 复制完成")} catch (e: IOException) {e.printStackTrace()}}
}
参考文献
1. Room | Jetpack | Android Developer
2. TheRouter 使用 KSP 处理注解
3. Android从Kapt迁移到ksp
4. 可用的KSP的版本