Android Room部件协同使用

Android 中的 Room 是 Google 官方推出的 SQLite 对象映射(ORM)库,用于简化本地数据库操作。它通过注解方式定义数据库结构,并自动生成底层实现,支持编译时 SQL 校验、LiveData 监听、协程等现代架构组件。


✅ Room 的三个核心部件

组件 作用说明
Entity 定义数据库表结构,每个类对应一张表,使用 @Entity 注解。
DAO(Data Access Object) 定义对表的增删改查操作,使用 @Dao 注解。
Database 数据库持有者,继承 RoomDatabase,使用 @Database 注解,包含所有实体和 DAO。

✅ 示例:使用 Room 管理用户表

1️⃣ 添加依赖(build.gradle

  • project build.gradle.kts
gradle 复制代码
plugins {
    id("com.android.application") version "8.1.4" apply false
    id("org.jetbrains.kotlin.android") version "1.9.22" apply false
    // ① 使用 KSP 生成 Room 代码(官方最新推荐)
    id("com.google.devtools.ksp") version "1.9.22-1.0.17" apply false
}
  • app build.gradle.kts
gradle 复制代码
plugins {
    id("com.android.application")
    id("org.jetbrains.kotlin.android")
    id("com.google.devtools.ksp")   // Room 注解处理器
}

android {
    compileSdk = 34
    defaultConfig {
        applicationId = "com.example.roomdemo"
        minSdk = 21
        targetSdk = 34
        versionCode = 1
        versionName = "1.0"
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }
    kotlinOptions.jvmTarget = "1.8"
}

dependencies {
    val roomVersion = "2.8.3"
    implementation("androidx.room:room-runtime:$roomVersion")
    ksp("androidx.room:room-compiler:$roomVersion")   // KSP 生成代码
    implementation("androidx.room:room-ktx:$roomVersion") // 协程扩展
    implementation("androidx.core:core-ktx:1.12.0")
}

2️⃣ 创建实体类Entity -> 表(User.kts)

kotlin 复制代码
@Entity(tableName = "user")
data class User(
    @PrimaryKey(autoGenerate = true) val id: Int = 0,
    val name: String,
    val age: Int
)

3️⃣ 创建 DAO 接口 -> SQL操作(UserDao.kts)

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

    @Query("SELECT * FROM user ORDER BY name ASC")
    fun getAllUsers(): Flow<List<User>>   // 返回 Flow,可观察

    @Delete
    suspend fun delete(user: User)
}

4️⃣ 创建数据库类 Database → 容器(AppDatabase.kts)

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

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

        fun get(context: Context): AppDatabase =
            INSTANCE ?: synchronized(this) {
                INSTANCE ?: Room.databaseBuilder(
                    context.applicationContext,
                    AppDatabase::class.java,
                    "app.db"
                ).build().also { INSTANCE = it }
            }
    }
}

5️⃣ 初始化并使用数据库: 协程+flow(MainActivity.kts)

kotlin 复制代码
class UserViewModel(app: Application) : AndroidViewModel(app) {
    private val dao = AppDatabase.get(app).userDao()

    val users: StateFlow<List<User>> = dao.getAllUsers()
        .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), emptyList())

    fun add(name: String, age: Int) = viewModelScope.launch {
        dao.insert(User(name = name, age = age))
    }

    fun delete(user: User) = viewModelScope.launch {
        dao.delete(user)
    }
}

可观察的 Compose 界面(仅关键代码)

kotlin 复制代码
@Composable
fun UserScreen(vm: UserViewModel = viewModel()) {
    val list by vm.users.collectAsState()

    Column {
        Button(onClick = { vm.add("Alice", 20) }) { Text("添加") }
        LazyColumn {
            items(list) { user ->
                Text("${user.name}  ${user.age}",
                    modifier = Modifier.clickable { vm.delete(user) })
            }
        }
    }
}

小结

部件 作用 是否必须
Entity 一张表 = 一个 @Entity data class
DAO 把 SQL 语句翻译成接口方法
Database 继承 RoomDatabase,提供 DAO 实例
KSP 取代 KAPT,编译更快 推荐
room-ktx 支持 suspend + Flow 推荐

✅ 小贴士

  • Room 不允许在主线程操作数据库 ,需使用异步线程、协程或 LiveData
  • 可配合 ViewModel + LiveData 实现生命周期感知的数据库操作 。

✅ 总结一句话

Room = Entity(表) + DAO(操作) + Database(数据库),三者配合实现类型安全、简洁高效的本地数据库管理。


相关推荐
codingFunTime1 天前
vue3 snapdom 导出图片和pdf
前端·javascript·pdf
橙子199110161 天前
Scaffold
android·kotlin·android jetpack
成为大佬先秃头1 天前
渐进式JavaScript框架:Vue 组件
前端·javascript·vue.js
程序员勾践1 天前
前端仅传path路径给后端,避免攻击
前端
登山人在路上1 天前
Vue 2 中响应式失效的常见情况
开发语言·前端·javascript
董世昌411 天前
创建对象的方法有哪些?
开发语言·前端
问道飞鱼1 天前
【前端知识】前端项目不同构建模式的差异
前端·webpack·构建·开发模式·生产模式
我命由我123451 天前
Android 消息机制 - Looper(Looper 静态方法、Looper 静态方法注意事项、Looper 实例方法、Looper 实例方法注意事项)
android·java·android studio·安卓·android jetpack·android-studio·android runtime
be or not to be1 天前
CSS 布局机制与盒模型详解
前端·css
消失的旧时光-19431 天前
从 JVM 到 Linux:一次真正的系统级理解
android·linux·jvm