将多个过滤器传递给 Android Room Dao SQL 使用 Repository 从 ViewModel 查询

Pass multiple Filters to Android Room Dao SQL Query from ViewModel with Repository

我正在使用下面的方法将数据库行获取到我的适配器,但是我想使用 "LIKE" and/or [=41= 从多重过滤的单个查询中获取 return 行] 和基本上所有 sql 查询过滤器类型,我可以通过 MutableLiveData<String>();

做一个过滤器

最终结果会是...

@Query("SELECT * FROM mytable WHERE suburb LIKE '%' || :suburb || '%' postcode LIKE '%' || :postcode || '%' BETWEEN firstDate AND lastDate")
fun getFilteredRows(
    suburb: String?, 
    postcode: String?, 
    firstDate: String?, 
    lastDate: String?): LiveData<List<MyTable>>

如下所示,目前只能通过一种过滤器变量。

视图模型Class

 class MyViewModel internal constructor(repository: MyRepository) : ViewModel()

 //filter by suburb
 var suburb = MutableLiveData<String>().apply { 
    //do I set as HashMap??
    value = SUBURB 
 }

 //LiveData Observer access
 val filteredRows: LiveData<List<MyTable>> = suburb.switchMap {

    //pass multiple filters to repository here
    //but currently only can pass one string to repository
    repository.getFilteredRows(it)

 }

 //MyViewModel function to set the suburb value
 fun setSuburb(_suburb: String) {
    suburb.value = _suburb
 }

 //companion object
 companion object {
    var SUBURB: String? = null
 }

存储库Class

class Repository private constructor(private val dao: Dao)

//basic repo to dao communtication
fun getFilteredRows(suburb: String?) = dao.getFilteredRows(suburb)

Dao 接口

@Dao
interface Dao

//here I want to receive multiple Strings to do filtering within the query
@Query("SELECT * FROM mytable WHERE suburb LIKE '%' || :suburb || '%'")
fun getFilteredRows(suburb: String?): LiveData<List<MyTable>>

我尝试过传递基本的 var 字符串,但没有成功,似乎只有 MutableLiveData 是通过 ViewModel & Repository

将变量传递给 Dao 的方法

** 见下方编辑 **

至少可以说不理想,实际上不推荐,但是,当前的解决方法是 "loop" 通过多个 MutableLiveData 变量

视图模型Class

var suburb = MutableLiveData<String>().apply { value = SUBURB }
var postcode = MutableLiveData<String>().apply { value = POSTCODE }
var limit = MutableLiveData<Int>().apply { value = LIMIT }

val filteredRows: LiveData<List<MyTable>> = 
    suburb.switchMap {

           //set suburb MutableLiveData
           var suburb = it

           postcode.switchMap {
              //set postcode MutableLiveData
              var postcode = it


            }

            limit.switchMap {
              //set limit MutableLiveData
              var limit = it


            }

    repository.getFilteredRows(suburb, postcode, limit)

} 

/// 编辑答案 ///

使用 HashMap 将多个过滤器(字符串)传递给 Dao SQl 查询。 测试了一个返回的预期结果,因此确认它有效。

可预见的问题是当需要传递字符串和 Int 等时,可能不得不参考仅作为字符串传递然后对 Int 字符串值执行 parse.ToInt() 等

在我的 Fragment 中构建 HashMap 以传递给 MyViewModel

lateinit var myModel: LiveData<MyTable>

var filters = HashMap<String, String>()
filters.put("suburb", myModel.value!!.suburb)
filters.put("postcode", myModel.value!!.postcode)


 with(viewModel) {

        //pass my HashMap to my ViewModel for update/change/set on filters MutableLiveData HashMap variable
        setFilters(filters)

 }

MyViewModel Class

 //initilise filters MutableLiveData HashMap variable
 var filters = MutableLiveData<HashMap<String, String>>().apply { value = FILTERS }


 //function to update/change/set filters MutableLiveData HashMap variable
 //see setFilters(filters) used in above Fragment
 fun setFilters(_filters: HashMap<String, String>) {
    filters.value = _filters
 }


 //foreach on passed HashMap via switchMap{}
 val filtered: LiveData<List<MyTable>> = filters.switchMap {

    //initilise variables
    var suburb = ""
    var postcode = ""

    //foreach loop on HashCookie :)
    for (filter in it) {
        if(filter.key.equals("suburb")){
            suburb = filter.value
        }else if(filter.key.equals("postcode")) {
            postcode = filter.value
        }
    }

    //pass strings to Dao
    repository.getFiltered(suburb, postcode)

 }

//companion object
companion object {
    var FILTERS: HashMap<String, String>? = null
 }

存储库Class

//send variables to the Dao Interface
fun getFiltered(suburb: String?, postcode: String?) = dao.getFiltered(suburb, postcode)

道接口

@Query("SELECT * FROM mytable WHERE suburb LIKE '%' || :suburb || '%' AND postcode LIKE '%' || :postcode || '%' ")
fun getFiltered(suburb: String?, postcode: String?): LiveData<List<MyTable>>