You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Jetpack Compose中对Room数据库执行增删改查操作?

在Jetpack Compose中实现Room的增删改查操作

你已经完成了Room的Entity、Dao和Database类,接下来可以通过仓库层(Repository)、ViewModel和Compose UI三层来实现完整的增删改查逻辑,步骤如下:

1. 创建仓库(Repository)层

仓库作为数据层的封装,统一处理Dao的操作,避免直接在ViewModel或UI层调用Dao:

class ItemRepository(private val itemDao: ItemDao) {
    // 暴露所有物品的Flow,直接复用Dao的查询结果
    val allItems: Flow<List<Item>> = itemDao.getAllItems()

    // 根据ID获取单个物品
    fun getItem(id: Int): Flow<Item> = itemDao.getItem(id)

    // 插入物品(suspend方法,需在协程中调用)
    suspend fun insertItem(item: Item) {
        itemDao.insert(item)
    }

    // 更新物品
    suspend fun updateItem(item: Item) {
        itemDao.update(item)
    }

    // 删除物品
    suspend fun deleteItem(item: Item) {
        itemDao.delete(item)
    }
}

2. 配置Application类(提供全局仓库实例)

创建自定义Application类,懒加载Database和Repository,方便在ViewModel中获取:

class InventoryApplication : Application() {
    // 懒加载Room数据库
    val database: InventoryDatabase by lazy { InventoryDatabase.getDatabase(this) }
    // 懒加载仓库
    val repository: ItemRepository by lazy { ItemRepository(database.itemDao()) }
}

记得在AndroidManifest.xml中声明这个Application:

<application
    android:name=".InventoryApplication"
    ...>
    ...
</application>

3. 创建ViewModel层

ViewModel负责处理业务逻辑,将数据状态暴露给UI层,同时用viewModelScope处理协程:

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.launch

class ItemViewModel(private val repository: ItemRepository) : ViewModel() {
    // 所有物品的Flow,直接传递仓库的Flow
    val allItems: Flow<List<Item>> = repository.allItems

    // 根据ID获取单个物品
    fun getItem(id: Int): Flow<Item> = repository.getItem(id)

    // 插入物品:用viewModelScope启动协程执行suspend方法
    fun insertItem(item: Item) {
        viewModelScope.launch {
            repository.insertItem(item)
        }
    }

    // 更新物品
    fun updateItem(item: Item) {
        viewModelScope.launch {
            repository.updateItem(item)
        }
    }

    // 删除物品
    fun deleteItem(item: Item) {
        viewModelScope.launch {
            repository.deleteItem(item)
        }
    }
}

// ViewModel工厂类,用于向ViewModel注入Repository
class ItemViewModelFactory(private val repository: ItemRepository) : ViewModelProvider.Factory {
    @Suppress("UNCHECKED_CAST")
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        if (modelClass.isAssignableFrom(ItemViewModel::class.java)) {
            return ItemViewModel(repository) as T
        }
        throw IllegalArgumentException("Unknown ViewModel class")
    }
}

4. 在Compose UI层实现交互

在Compose中观察ViewModel的状态,调用增删改查方法:

主界面实现

import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsStateWithLifecycle
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val repository = (application as InventoryApplication).repository
        val viewModelFactory = ItemViewModelFactory(repository)
        setContent {
            MaterialTheme {
                val viewModel: ItemViewModel = viewModel(factory = viewModelFactory)
                InventoryScreen(viewModel)
            }
        }
    }
}

@Composable
fun InventoryScreen(viewModel: ItemViewModel) {
    // 用collectAsStateWithLifecycle观察Flow,自动处理生命周期
    val items by viewModel.allItems.collectAsStateWithLifecycle(initialValue = emptyList())

    Column(modifier = Modifier.fillMaxSize().padding(16.dp)) {
        // 添加物品按钮
        Button(onClick = {
            // 注意:ID设为0即可,Room会自动生成自增ID
            val newItem = Item(id = 0, name = "新物品", price = 10, quantity = 5)
            viewModel.insertItem(newItem)
        }) {
            Text(text = "添加新物品")
        }

        // 物品列表
        LazyColumn(modifier = Modifier.weight(1f).padding(top = 16.dp)) {
            items(items) { item ->
                ItemCard(
                    item = item,
                    onUpdate = { updatedItem ->
                        viewModel.updateItem(updatedItem)
                    },
                    onDelete = {
                        viewModel.deleteItem(item)
                    }
                )
            }
        }
    }
}

@Composable
fun ItemCard(item: Item, onUpdate: (Item) -> Unit, onDelete: () -> Unit) {
    Card(
        modifier = Modifier.fillMaxWidth().padding(8.dp),
        elevation = CardDefaults.cardElevation(4.dp)
    ) {
        Column(modifier = Modifier.padding(16.dp)) {
            Text(text = "名称: ${item.name}", fontSize = 18.sp, fontWeight = FontWeight.Bold)
            Text(text = "价格: ${item.price} 元")
            Text(text = "库存: ${item.quantity} 件")

            Row(
                modifier = Modifier.fillMaxWidth().padding(top = 12.dp),
                horizontalArrangement = Arrangement.End
            ) {
                Button(
                    onClick = {
                        // 示例:库存+1
                        val updatedItem = item.copy(quantity = item.quantity + 1)
                        onUpdate(updatedItem)
                    },
                    modifier = Modifier.padding(end = 8.dp)
                ) {
                    Text(text = "库存+1")
                }
                Button(
                    onClick = onDelete,
                    colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.error)
                ) {
                    Text(text = "删除")
                }
            }
        }
    }
}

5. 必要的依赖补充

确保你的build.gradle(Module级)中包含以下依赖:

dependencies {
    // Room核心依赖
    implementation "androidx.room:room-runtime:2.6.1"
    kapt "androidx.room:room-compiler:2.6.1"
    // Room Kotlin协程支持
    implementation "androidx.room:room-ktx:2.6.1"
    // Lifecycle Compose支持(用于collectAsStateWithLifecycle)
    implementation "androidx.lifecycle:lifecycle-runtime-compose:2.7.0"
    // ViewModel Compose支持
    implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.7.0"
    // Material3(如果使用Material3主题)
    implementation "androidx.compose.material3:material3:1.2.0"
}

注意事项

  • Room的@Insert方法中,自增ID字段传0即可,Room会自动生成唯一ID。
  • collectAsStateWithLifecycle会自动根据Activity/Fragment的生命周期启动/停止收集Flow,避免内存泄漏。
  • 所有Dao的suspend方法必须在协程中调用,这里通过ViewModel的viewModelScope来管理协程生命周期。

内容的提问来源于stack exchange,提问作者Jorpy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 23:28:19