Room更新实体无法修改数据库值问题求助
问题分析
你的Room更新操作无效的核心原因是:Room的@Update注解是通过主键匹配来定位要更新的行。
你的BaseCurrencyModel主键是baseCurrency字段,当你创建BaseCurrencyModel(selectedCurrency)调用更新时,Room会在base_currency表中寻找主键等于selectedCurrency的行。但数据库中只有初始化时的默认基准货币条目(比如假设默认是"USD"),找不到对应新主键的行,因此不会执行任何更新操作。
解决方案
针对基准货币表仅存一条数据的场景,推荐以下两种简洁的解决方式:
方案1:使用@Insert配合冲突替换(最推荐)
因为基准货币表只需要保留一条数据,直接用「插入时替换冲突行」的逻辑,不管原有主键是什么,都会替换成新的基准货币:
- 修改DAO中的方法:
@Insert(onConflict = OnConflictStrategy.REPLACE) fun insertOrReplaceBaseCurrency(baseCurrencyModel: BaseCurrencyModel)
- 对应修改Repository和ViewModel的方法名,调用这个新方法即可,原有Spinner的调用逻辑无需改动——插入新条目时,因为主键冲突,Room会自动替换掉原来的基准货币行。
方案2:直接用@Query写更新SQL
跳过主键匹配逻辑,直接更新表中唯一的行:
- 修改DAO中的方法:
@Query("UPDATE base_currency SET base_curr = :newBaseCurrency") fun updateBaseCurrency(newBaseCurrency: String)
- 后续调用时无需创建
BaseCurrencyModel对象,直接传入选中的货币字符串即可,简化代码逻辑。
额外优化点
你在updateBaseCurrency函数中额外创建了CoroutineScope(Dispatchers.IO),但ViewModel的updateCurrency方法已经通过viewModelScope启动了IO协程,无需额外嵌套协程,避免不必要的内存泄漏风险:
private fun updateBaseCurrency(selectedCurrency: String) { val newBase = BaseCurrencyModel(selectedCurrency) Log.i(TAG, "updateBaseCurrency: $selectedCurrency || $newBase") // 直接调用ViewModel方法即可,无需额外创建协程 mDatabaseViewModel.updateCurrency(newBase) }
内容的提问来源于stack exchange,提问作者StuckedForeva
相关产品推荐
相关产品推荐

