这种在ROOM数据库中过滤数据的方式有错吗?

问题描述 投票:0回答:1

我有一个待办事项列表应用程序,其中使用了 ROOM 数据库。该应用程序还具有一些过滤功能,因此用户可以根据标题、优先级或描述来过滤列表。 我想知道我在 viewModel 中实现过滤的方式是否有效?如果不是,最好的方法是什么?

我的DAO:

@Dao
interface ToDoDao {

    @Insert(ToDoData::class, onConflict = OnConflictStrategy.IGNORE)
    suspend fun insert(toDoData: ToDoData)

    @Delete(ToDoData::class)
    suspend fun delete(item: ToDoData)

    @Update(ToDoData::class,onConflict = OnConflictStrategy.IGNORE)
    suspend fun update(item: ToDoData)

    @Query("DELETE FROM TODO_TABLE")
    suspend fun deleteAllData()

    @Query("SELECT * FROM TODO_TABLE ORDER BY id ASC ")
    fun getAllData():LiveData<List<ToDoData>>


    @Query("SELECT * FROM TODO_TABLE ORDER BY CASE WHEN priority LIKE 'H%' THEN 1 WHEN priority LIKE 'M%' THEN 2 WHEN priority LIKE 'L%' THEN 3 END")
    fun getAllDataSortedByHighPriority():LiveData<List<ToDoData>>

    @Query("SELECT * FROM TODO_TABLE ORDER BY CASE WHEN priority LIKE 'L%' THEN 1 WHEN priority LIKE 'M%' THEN 2 WHEN priority LIKE 'H%' THEN 3 END")
    fun getAllDataSortedByLowPriority():LiveData<List<ToDoData>>

    @Query("SELECT * FROM TODO_TABLE WHERE title LIKE '%' || :titleContains || '%' AND priority IN (:prioritiesIn) AND description LIKE '%' || :descContains || '%' ORDER BY ID ASC")
    fun filterDataSortedByID(titleContains: String, prioritiesIn:Array<Priority>,descContains:String):LiveData<List<ToDoData>>

}

我的存储库:

class ToDoRepository(private val dao: ToDoDao) {

    val allData: LiveData<List<ToDoData>> = dao.getAllData()
    val allDataSortedByHighPriority = dao.getAllDataSortedByHighPriority()
    val allDataSortedByLowPriority = dao.getAllDataSortedByLowPriority()


    suspend fun insert(item: ToDoData) {
        dao.insert(item)
    }

    suspend fun delete(item: ToDoData) {
        dao.delete(item)
    }

    suspend fun update(item: ToDoData) {
        dao.update(item)
    }

    suspend fun deleteAll(){
        dao.deleteAllData()
    }

    fun filterDataSortedByID(titleContains: String, prioritiesIn:Array<Priority>,descContains:String):LiveData<List<ToDoData>>{
        return dao.filterDataSortedByID(titleContains,prioritiesIn,descContains)
    }

}

我的观点模型:

class ToDoViewModel(context: Application) : AndroidViewModel(context) {

    private val toDoDao = ToDoDatabase.getDataBase(context.applicationContext).toDoDao()
    private val repository = ToDoRepository(toDoDao)

    private val filters: MutableLiveData<MutableMap<String, Any>> =
        MutableLiveData(
            mutableMapOf(
                "titleContains" to "",
                "prioritiesIn" to arrayOf(Priority.HIGH, Priority.MEDIUM, Priority.LOW),
                "descContains" to "",
            )
        )


    var titleContains: String
        get() = filters.value?.get("titleContains") as String
        set(value) {
            filters.value = filters.value?.apply {
                set("titleContains", value)
            }
        }
    var prioritiesIn: Array<Priority>
        get() = filters.value?.get("prioritiesIn") as Array<Priority>
        set(value) {
            filters.value = filters.value?.apply {
                set("prioritiesIn", value)
            }
        }
    var descContains: String
        get() = filters.value?.get("descContains") as String
        set(value) {
            filters.value = filters.value?.apply {
                set("descContains", value)
            }
        }


    val filteredData = filters.switchMap { _ ->
        if (titleContains.isEmpty() && descContains.isEmpty()) {
            repository.allData
        } else {
            repository.filterDataSortedByID(titleContains, prioritiesIn, descContains)
        }
    }


    fun insertData(item: ToDoData) {
        viewModelScope.launch {
            repository.insert(item)
        }
    }

    fun updateData(item: ToDoData) {
        viewModelScope.launch {
            repository.update(item)
        }
    }

    fun deleteData(item: ToDoData) {
        viewModelScope.launch {
            repository.delete(item)
        }
    }

    fun deleteAll() {
        viewModelScope.launch {
            repository.deleteAll()
        }
    }


}
android kotlin android-room android-viewmodel android-architecture-components
1个回答
0
投票

小心

LIKE '%xyz%'
- 它需要全表扫描才能获取结果,因为它不能使用索引。

看看 FTS(全文搜索)。搜索“Android Room FTS”,您会找到几篇文章和教程。 这个看起来不错,但已经有几年了。

FTS 还允许您同时搜索

title
description
(或任何其他列)。这对于用户来说可能更灵活,而不是需要单独的条目。

© www.soinside.com 2019 - 2024. All rights reserved.