Android Jetpack Room 新手使用指南

Room 是 Android Jetpack 中的 SQLite 对象映射库,用于简化本地数据库操作,提供编译时 SQL 校验、LiveData/Flow 集成、RxJava 支持等功能。本文将从以下其核心概念、使用示例、适用场景、注意事项及版本兼容性等方面进行讲解。

一、核心组件

1. Entity(实体类)

  • 定义数据库表结构,通过注解配置主键、列名、索引等。

2. DAO(Data Access Object)

  • 接口或抽象类,定义数据库操作方法(增删改查)。

3. Database(数据库类)

  • 继承 RoomDatabase 的抽象类,管理数据库连接和 DAO 实例。

二、使用示例

1. 基础配置

添加依赖

gradle 复制代码
// build.gradle (app)
dependencies {
    implementation "androidx.room:room-runtime:2.6.1"
    kapt "androidx.room:room-compiler:2.6.1"
    implementation "androidx.room:room-ktx:2.6.1" // Kotlin扩展
    // 可选:RxJava或Paging集成
    implementation "androidx.room:room-rxjava3:2.6.1"
    implementation "androidx.room:room-paging:2.6.1"
}

2. 定义 Entity

kotlin 复制代码
@Entity(tableName = "users", indices = [Index(value = ["name"], unique = true)])
data class User(
    @PrimaryKey(autoGenerate = true)
    val id: Int = 0,
    @ColumnInfo(name = "name")
    val userName: String,
    val age: Int,
    @ColumnInfo(defaultValue = "false")
    val isAdmin: Boolean
)

3. 定义 DAO

kotlin 复制代码
@Dao
interface UserDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insert(user: User)

    @Update
    suspend fun update(user: User)

    @Delete
    suspend fun delete(user: User)

    @Query("SELECT * FROM users WHERE id = :userId")
    fun getUserById(userId: Int): Flow<User?>

    @Query("SELECT * FROM users WHERE isAdmin = 1")
    fun getAdmins(): PagingSource<Int, User> // 与Paging集成
}

4. 定义 Database

kotlin 复制代码
@Database(
    entities = [User::class],
    version = 1,
    exportSchema = true
)
abstract class AppDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao

    companion object {
        @Volatile
        private var instance: AppDatabase? = null

        fun getInstance(context: Context): AppDatabase {
            return instance ?: synchronized(this) {
                instance ?: buildDatabase(context).also { instance = it }
            }
        }

        private fun buildDatabase(context: Context): AppDatabase {
            return Room.databaseBuilder(
                context.applicationContext,
                AppDatabase::class.java,
                "app_database"
            ).addCallback(object : RoomDatabase.Callback() {
                override fun onCreate(db: SupportSQLiteDatabase) {
                    super.onCreate(db)
                    // 数据库首次创建时初始化数据
                }
            }).build()
        }
    }
}

5. 在 ViewModel 中操作数据

kotlin 复制代码
class UserViewModel(private val userDao: UserDao) : ViewModel() {
    val admins: Flow<List<User>> = userDao.getAdmins().flowOn(Dispatchers.IO)

    fun addUser(name: String, age: Int) {
        viewModelScope.launch {
            userDao.insert(User(userName = name, age = age))
        }
    }
}

6. 数据库迁移(版本升级)

kotlin 复制代码
// 版本1 → 版本2:新增字段 email
val MIGRATION_1_2 = object : Migration(1, 2) {
    override fun migrate(database: SupportSQLiteDatabase) {
        database.execSQL("ALTER TABLE users ADD COLUMN email TEXT DEFAULT ''")
    }
}

// 更新Database配置
Room.databaseBuilder(...)
    .addMigrations(MIGRATION_1_2)
    .build()

三、适用场景

1. 本地数据持久化

  • 用户信息、应用配置、缓存数据等需持久化存储的场景。

2. 复杂查询需求

  • 多表关联查询、聚合函数(SUM/COUNT)等。

3. 离线优先架构

  • 结合 RemoteMediator 实现先加载本地数据,再同步远程数据。

4. 响应式 UI

  • 通过 FlowLiveData 监听数据变化,实时更新界面。

四、注意事项

1. 主线程限制

  • 默认禁止在主线程执行数据库操作,需使用协程、RxJava 或异步任务。

  • 调试时可临时启用 allowMainThreadQueries(),但生产环境禁用。

    kotlin 复制代码
    Room.databaseBuilder(...)
        .allowMainThreadQueries() // 仅用于测试
        .build()

2. 索引优化

  • 对高频查询字段(如 name)添加索引,但避免过度索引导致写入性能下降。

    kotlin 复制代码
    @Entity(indices = [Index(value = ["name"], orders = [Order.ASC])])

3. 数据库升级风险

  • 修改表结构时需谨慎处理迁移逻辑,建议使用 MigrationTestHelper 进行单元测试。

    kotlin 复制代码
    @Test
    fun testMigration1To2() {
        val helper = MigrationTestHelper(...)
        val db = helper.runMigrationsAndValidate("app_database", 2, true, MIGRATION_1_2)
        // 验证字段是否存在
    }

4. 类型转换

  • 复杂类型(如 Date)需通过 TypeConverter 序列化:

    kotlin 复制代码
    class Converters {
        @TypeConverter
        fun fromTimestamp(value: Long?) = value?.let { Date(it) }
    
        @TypeConverter
        fun dateToTimestamp(date: Date?) = date?.time
    }

    @Database 注解中添加:

    kotlin 复制代码
    @TypeConverters(Converters::class)

五、版本兼容性

Room 版本 最低 Android API 主要特性
2.2.x API 16 (Android 4.1) 支持 Kotlin 协程、预编译数据库。
2.4.x API 16 增强 Flow 支持、改进 Paging 3 集成。
2.5.x API 16 支持 Upsert 注解、自动迁移(AutoMigration)。
2.6.x API 16 提升性能、支持 @Fts4 全文搜索注解。
  • AutoMigration(自动迁移)

    从 Room 2.4.0 开始,若表结构变更仅涉及新增/删除列,可自动生成迁移逻辑:

    kotlin 复制代码
    @Database(
        version = 2,
        autoMigrations = [
            AutoMigration(from = 1, to = 2)
        ]
    )

六、与 Hilt 集成(依赖注入)

一文带你了解 Android 中 Dagger/Hilt 的原理和简单使用

kotlin 复制代码
@Module
@InstallIn(SingletonComponent::class)
object DatabaseModule {
    @Provides
    @Singleton
    fun provideAppDatabase(@ApplicationContext context: Context): AppDatabase {
        return AppDatabase.getInstance(context)
    }

    @Provides
    fun provideUserDao(database: AppDatabase): UserDao {
        return database.userDao()
    }
}

// 在 ViewModel 中注入
@HiltViewModel
class UserViewModel @Inject constructor(
    private val userDao: UserDao
) : ViewModel() { ... }

七、总结

  • 优势:编译时 SQL 校验、与 Jetpack 组件深度集成、简化数据库操作。

  • 最佳实践

    • 使用 FlowLiveData 实现响应式 UI。
    • 通过 TypeConverter 处理复杂数据类型。
    • 利用 AutoMigration 简化数据库升级。
    • 使用 @Transaction 确保多步骤操作的原子性。
    kotlin 复制代码
    @Dao
    interface UserDao {
        @Transaction
        suspend fun updateUserName(oldName: String, newName: String) {
            // 多个操作在一个事务中执行
        }
    }

通过合理使用 Room,开发者可以高效管理本地数据,提升应用的稳定性和可维护性。

更多分享

  1. 一文吃透Kotlin中冷流(Clod Flow)和热流(Hot Flow)
  2. 一文带你吃透Kotlin协程的launch()和async()的区别
  3. Kotlin 作用域函数(let、run、with、apply、also)的使用指南
  4. Android 详解:高频使用的 8 种设计模式的核心思想和代码实现
  5. 一文带你吃透Kotlin中 lateinit 和 by lazy 的区别和用法
  6. Android ContentProvider 详解及结合 Jetpack Startup 的优化实践
相关推荐
JQ_Zhang3 小时前
移动端H5弹窗“滚动穿透”的终极解决方案:为什么 overflow: hidden 没用?
app
ljt27249606615 小时前
Compose笔记(六十一)--SelectionContainer
android·笔记·android jetpack
逃离IDE6 小时前
React Native 视图拍平(View Flattening)详解
app
Kapaseker12 小时前
三分钟搞懂 Kotlin Flow 中的背压
android·kotlin
QING61813 小时前
Jetpack Compose 中的 ViewModel 作用域管理 —— 新手指南
android·kotlin·android jetpack
惟恋惜1 天前
Jetpack Compose 的状态使用之“界面状态”
android·android jetpack
KotlinKUG贵州1 天前
Kotlin/Ktor 实践:利用 MCP 从零打造 AI Agent 服务端指南
kotlin·agent·mcp
喜熊的Btm1 天前
探索 Kotlin 的不可变集合库
kotlin·android jetpack
俩毛豆1 天前
基于HarmonyOS(NEXT)的超级App中的搜索架构实现(直播文字干货版)
成长·架构·app·harmonyos·搜索
惟恋惜1 天前
Jetpack Compose 界面元素状态(UI Element State)详解
android·ui·android jetpack