我有一个待办事项列表应用程序,其中使用了 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()
}
}
}
小心
LIKE '%xyz%'
- 它需要全表扫描才能获取结果,因为它不能使用索引。
看看 FTS(全文搜索)。搜索“Android Room FTS”,您会找到几篇文章和教程。 这个看起来不错,但已经有几年了。
FTS 还允许您同时搜索
title
和 description
(或任何其他列)。这对于用户来说可能更灵活,而不是需要单独的条目。