2. 项目配置与依赖引入:Gradle依赖添加、KSP/KAPT插件选择、Schema导出配置、数据库版本管理
项目配置是Room数据库开发的起点,选择正确的编译插件、依赖版本和Schema导出策略直接关系到代码生成效率、迁移测试可靠性及长期维护成本。本章逐一拆解 Gradle 配置中的关键选项,并提供经过验证的推荐方案。
2.1 Gradle 依赖添加
Room 官方提供了三个核心模块,分别对应运行时、编译时注解处理、测试辅助。
版本对齐原则: Room 版本必须匹配同一主版本的 Kotlin 和 Compose BOM。例如 Room 2.6.1 要求 Kotlin 1.9.22+,KSP 1.9.22-1.0.17。始终检查 Room 发布说明 中的兼容性矩阵。
典型 build.gradle.kts (Module: app) 配置如下:
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("com.google.devtools.ksp") version "1.9.22-1.0.17" // 或 id("org.jetbrains.kotlin.kapt")
}
android {
// ... 其他配置
defaultConfig {
// schema 导出路径(详见 2.3 节)
javaCompileOptions {
annotationProcessorOptions {
arguments["room.schemaLocation"] = "$projectDir/schemas"
}
}
ksp {
arg("room.schemaLocation", "$projectDir/schemas")
}
}
}
dependencies {
implementation("androidx.room:room-runtime:2.6.1")
implementation("androidx.room:room-ktx:2.6.1")
// 使用 KSP (推荐) 或 KAPT 处理器
ksp("androidx.room:room-compiler:2.6.1")
// kapt("androidx.room:room-compiler:2.6.1")
// 可选:用于 Room 迁移测试
testImplementation("androidx.room:room-testing:2.6.1")
// 可选:Paging 3 集成
implementation("androidx.room:room-paging:2.6.1")
}
2.2 KSP 与 KAPT 插件选择
Room 编译时注解处理支持两种方式:KSP(Kotlin Symbol Processing)和 KAPT(Kotlin Annotation Processing Tool)。它们的核心差异如下:
| 维度 | KSP(推荐) | KAPT |
|---|---|---|
| 编译速度 | 快(跳过 Java stubs 生成) | 较慢(需生成 stubs) |
| IDE 兼容性 | 需 Gradle 8.0+,Kotlin 1.6.10+ | 更广泛支持旧版本 |
| 增量编译 | 原生支持 | 受限于 stub 生成 |
| 房间功能 | 完全支持(Room 2.5+) | 完全支持 |
| 迁移成本 | 需切换 Gradle 插件 | 默认,无需改动 |
| 社区趋势 | 主流推荐 | 逐步淘汰 |
重要: 切勿同时在项目中同时声明
ksp() 和 kapt() 依赖 room-compiler。这将导致重复生成代码,引发 Duplicate class 构建错误。请统一使用其中一种。
2.3 Schema 导出配置
Room 可以将数据库 Schema(表结构、索引、外键等)导出为 JSON 文件,用于自动化迁移测试。配置分为两步:
- 指定输出目录:在
build.gradle.kts的defaultConfig中设置room.schemaLocation。 - 编写迁移测试:引用导出的 Schema 文件验证迁移路径的正确性。
实战经验: 将 schema 目录纳入版本控制,并在 CI 中对每次数据库版本升级运行迁移测试。这能从构建阶段捕获破坏性变更,避免线上事故。
导出后的 JSON 文件示例(节选):
{
"formatVersion": 1,
"database": {
"version": 2,
"identityHash": "a1b2c3d4e5f6...",
"entities": [
{
"tableName": "users",
"createSql": "CREATE TABLE IF NOT EXISTS `users` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `name` TEXT NOT NULL, `age` INTEGER NOT NULL DEFAULT 18)",
"fields": [...]
}
],
"setupQueries": [...]
}
}
2.4 数据库版本管理
数据库版本通过 @Database 注解的 version 属性定义。管理策略需预先规划:
| 策略 | 适用场景 | 代码配置 |
|---|---|---|
| 递增版本号 | 所有正式发布 | @Database(version = 3) |
| fallbackToDestructiveMigration | 开发阶段、测试环境 | .fallbackToDestructiveMigration() |
| 导出 Schema + 手动 Migration | 生产环境版本升级 | .addMigrations(MIGRATION_2_3) |
// 定义数据库,版本 2
@Database(entities = [User::class], version = 2, exportSchema = true)
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
}
// Room.databaseBuilder 中使用
val db = Room.databaseBuilder(
applicationContext,
AppDatabase::class.java,
"app_database"
)
.addMigrations(MIGRATION_1_2) // 手动迁移(推荐生产场景)
.fallbackToDestructiveMigration() // 仅限开发测试
.build()
避坑指南: 在已上线的应用中不要使用
fallbackToDestructiveMigration()。它会丢弃所有用户数据。正确的做法是为每个版本编写 Migration 对象,并通过 CI 测试验证。
2.5 配置流程总览
下图总结了从 Gradle 插件选择到数据库版本管理的完整配置链路:
2.6 常见配置错误与修复
- KSP 与 KAPT 同时声明 → 删除其中一个插件和依赖声明。
- Schema 路径不存在 → 确保
$projectDir/schemas目录已创建或 Gradle 会自动生成。 - 版本号跳号 → 迁移代码必须覆盖所有中间版本,例如从版本 1 升到 3 需要
Migrations(1,2)和Migrations(2,3)。 - Kotlin 与 Room 版本不兼容 → 查阅 Room 发布说明中的兼容性矩阵,必要时降级 Room 或升级 Kotlin。