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


相关推荐
GIS之路19 小时前
GDAL 实现影像裁剪
前端·python·arcgis·信息可视化
AGMTI19 小时前
webSock动态注册消息回调函数功能实现
开发语言·前端·javascript
不会Android的潘潘20 小时前
受限系统环境下的 WebView 能力演进:车载平台 Web 渲染异常的根因分析与优化实践
android·java·前端·aosp
建军啊20 小时前
java web常见lou洞
android·java·前端
阳无20 小时前
宝塔部署的前后端项目从IP访问改成自定义域名访问
java·前端·部署
Galloping-Vijay20 小时前
解决 WSL2 + Windows Hosts + 开启 VPN 后无法访问本地 Web 服务的问题
前端·windows
豆奶dudu20 小时前
安卓应用签名生成+微信开放平台安卓应用签名
android·微信开放平台
wuhen_n20 小时前
TypeScript的对象类型:interface vs type
前端·javascript·typescript
见路不走!20 小时前
后端返回Blob文件流,前端实现导出
前端
lindd91191120 小时前
4G模块应用,内网穿透,前端网页的制作第七讲(智能头盔数据上传至网页端)
前端·后端·零基础·rt-thread·实时操作系统·项目复刻