什么是 Room,为什么需要它?
Room 是一个用于在 Kotlin 或 Java 编写的 Android 应用中处理数据库的库。它在 SQLite 之上提供了一个抽象层,允许通过面向对象的方式处理数据库,而不是使用原始 SQL 查询。
Room 的主要优势:
- 最小化样板代码 — Room 基于注解自动生成用于处理 SQLite 的代码。
- 编译时 SQL 查询检查 — 查询中的错误在应用运行前就能被发现。
- 与 Coroutines 和 Flow 集成 — 支持响应式编程和异步操作。
- 数据库迁移 — 内置机制用于更新模式而不丢失数据。
- TypeConverters — 能够在数据库中存储复杂数据类型(例如 Date、List)。
Room 非常适合需要本地存储结构化数据的应用:笔记、缓存、用户设置、离线模式等。
安装 Room
Room 不能通过 pip 或 npm 安装,因为它是 Android 库。通过 build.gradle 文件(模块级别)将其添加到项目中。
步骤 1:添加 KSP 插件(Kotlin Symbol Processing)
在根目录的 build.gradle 中添加 KSP 插件:
plugins { id 'com.google.devtools.ksp' version '1.9.0-1.0.13' apply false}步骤 2:在应用模块中连接 Room
在 app 模块的 build.gradle 中添加:
plugins { id 'com.android.application' id 'org.jetbrains.kotlin.android' id 'com.google.devtools.ksp'}
android { // ... 您的配置}
dependencies { def room_version = "2.6.1"
implementation "androidx.room:room-runtime:$room_version" ksp "androidx.room:room-compiler:$room_version" implementation "androidx.room:room-ktx:$room_version" // 用于 Coroutines}同步 Gradle 后,库即可使用。
快速入门及代码示例
创建一个简单的用于存储任务列表(Todo)的应用。
步骤 1:定义实体(Entity)
import androidx.room.Entityimport androidx.room.PrimaryKey
@Entity(tableName = "tasks")data class Task( @PrimaryKey(autoGenerate = true) val id: Int = 0, val title: String, val description: String, val isCompleted: Boolean = false)步骤 2:创建 DAO(数据访问对象)
import androidx.room.*import kotlinx.coroutines.flow.Flow
@Daointerface TaskDao { @Query("SELECT * FROM tasks ORDER BY id DESC") fun getAllTasks(): Flow<List<Task>>
@Insert suspend fun insertTask(task: Task)
@Update suspend fun updateTask(task: Task)
@Delete suspend fun deleteTask(task: Task)}步骤 3:创建数据库
import android.content.Contextimport androidx.room.Databaseimport androidx.room.Roomimport androidx.room.RoomDatabase
@Database(entities = [Task::class], version = 1)abstract class AppDatabase : RoomDatabase() { abstract fun taskDao(): TaskDao
companion object { @Volatile private var INSTANCE: AppDatabase? = null
fun getDatabase(context: Context): AppDatabase { return INSTANCE ?: synchronized(this) { val instance = Room.databaseBuilder( context.applicationContext, AppDatabase::class.java, "app_database" ).build() INSTANCE = instance instance } } }}