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
相关产品推荐
相关产品推荐

