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(数据库),三者配合实现类型安全、简洁高效的本地数据库管理。


相关推荐
IT_陈寒14 分钟前
Vite的public文件夹放静态资源?这坑我替你踩了
前端·人工智能·后端
涵涵(互关)27 分钟前
GoView各项目文件中的相关语法2
前端·javascript·vue.js
子兮曰34 分钟前
别让爬虫白嫖你的导航站了:纯免费,手把手实现加密字体防爬
前端·javascript·后端
小村儿1 小时前
连载06 - Hooks 源码深度解析:Claude Code 的确定性自动化体系
前端·后端·ai编程
心中无石马1 小时前
uniapp引入tailwindcss4.x
前端·css·uni-app
焰火19991 小时前
[Vue]可重置的响应式状态reactive
前端·vue.js
陆枫Larry1 小时前
CSS transform scale:图片放大效果背后的原理
前端
老王以为2 小时前
为什么 React 和 Vue 不一样?
前端·vue.js·react.js
web打印社区2 小时前
2026最新Web静默打印解决方案,无插件无预览,完美替代Lodop
前端·javascript·vue.js·electron·pdf
这个DBA有点耶2 小时前
分组排名不用窗口函数?那你还在写几十行的子查询
前端·代码规范