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

Room数据库条件查询:Repository与ViewModel层参数传递求助

解决Room条件查询的参数传递问题

看起来你在Room的条件查询和参数传递上卡壳了,我来一步步帮你梳理清楚:

首先先修正你DAO里的语法小问题:LIKE和参数占位符:parent之间不能有空格,否则Room会识别错误,正确的DAO写法应该是:

@Dao
interface AppDao {
    @Query("SELECT * FROM apps WHERE parent LIKE :parent")
    fun getAllApp(parent: String): LiveData<List<App>>
}

接下来分Repository和ViewModel两层来说怎么传递参数:

1. Repository层封装数据操作

Repository作为数据层的封装,需要持有AppDao的实例,然后提供一个接收参数并调用DAO方法的函数,直接返回LiveData即可:

class AppRepository(private val appDao: AppDao) {
    // 接收parent参数,调用DAO的查询方法返回LiveData
    fun getFilteredApps(parent: String): LiveData<List<App>> {
        return appDao.getAllApp(parent)
    }
}

2. ViewModel层连接UI和数据层

ViewModel需要持有Repository的实例,这里推荐用ViewModelProvider.Factory来注入Repository(避免ViewModel里直接实例化,符合依赖注入的思想),然后提供一个方法让UI层传递参数,或者借助Transformations.switchMap实现参数变化自动触发查询:

class AppViewModel(private val repository: AppRepository) : ViewModel() {
    // 定义MutableLiveData接收UI层传入的查询参数
    private val _parentQuery = MutableLiveData<String>()
    
    // 用switchMap监听参数变化,自动触发新的查询
    val filteredApps: LiveData<List<App>> = Transformations.switchMap(_parentQuery) { parent ->
        repository.getFilteredApps(parent)
    }

    // 暴露给UI层的方法,用来传递查询参数
    fun setParentQuery(parent: String) {
        _parentQuery.value = parent
    }
}

// 对应的ViewModel Factory,用于注入Repository
class AppViewModelFactory(private val repository: AppRepository) : ViewModelProvider.Factory {
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        if (modelClass.isAssignableFrom(AppViewModel::class.java)) {
            @Suppress("UNCHECKED_CAST")
            return AppViewModel(repository) as T
        }
        throw IllegalArgumentException("Unknown ViewModel class")
    }
}

3. UI层(Activity/Fragment)使用

在UI层,你需要初始化ViewModel,然后调用setParentQuery传递参数,再观察filteredApps的变化来更新UI:

class MainActivity : AppCompatActivity() {
    private lateinit var viewModel: AppViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // 初始化数据库、DAO、Repository和ViewModel
        val appDatabase = AppDatabase.getInstance(application)
        val appDao = appDatabase.appDao()
        val repository = AppRepository(appDao)
        val viewModelFactory = AppViewModelFactory(repository)
        viewModel = ViewModelProvider(this, viewModelFactory)[AppViewModel::class.java]

        // 传递查询参数,比如查询parent为"system"的应用
        viewModel.setParentQuery("system")

        // 观察LiveData变化,更新UI
        viewModel.filteredApps.observe(this) { apps ->
            // 这里处理查询到的应用列表,比如刷新RecyclerView
            updateAppList(apps)
        }
    }

    private fun updateAppList(apps: List<App>) {
        // 你的UI更新逻辑
    }
}

另外,如果需要模糊匹配(比如包含某个字符串的parent),可以在传递参数时加上SQL通配符:

// 匹配所有包含"sys"的parent
viewModel.setParentQuery("%sys%")

这样就能实现动态的条件查询了,核心是通过ViewModel接收UI层的参数,再传递给Repository,最终调用DAO的查询方法,借助LiveData的特性自动更新UI。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 12:57:43