Android:如何从Room数据库按条件筛选项目经理下属的指定状态设备?
解决方案
思路说明
当前实体类通过TypeConverter将员工列表、设备列表以JSON字符串形式存储在Room数据库中,无法直接通过SQL查询嵌套的设备状态。因此需要先获取所有项目经理数据,再在内存中完成过滤处理,最终保留包含符合状态设备的员工及对应项目经理。
具体实现步骤
1. 从数据库获取全量项目经理数据
先通过Room Dao接口查询所有项目经理记录:
@Dao interface ProjectManagerDao { @Query("SELECT * FROM $TABLE_PROJECT_MANAGER") suspend fun getAllProjectManagers(): List<ProjectManager> }
2. 编写过滤逻辑
根据目标设备状态(targetStatus: Int,值为0或1),对全量数据进行多层过滤:
fun filterProjectManagersByDeviceStatus( allManagers: List<ProjectManager>, targetStatus: Int ): List<ProjectManager> { return allManagers.mapNotNull { manager -> // 过滤员工:仅保留拥有符合状态设备的员工,同时更新该员工的设备列表为仅包含目标状态的设备 val filteredEmployees = manager.employees.mapNotNull { employee -> val filteredDevices = employee.devices?.filter { it.status == targetStatus } filteredDevices?.takeIf { it.isNotEmpty() }?.let { employee.copy(devices = it) } } // 仅保留拥有有效下属员工的项目经理,同时更新其员工列表为过滤后的结果 filteredEmployees.takeIf { it.isNotEmpty() }?.let { manager.copy(employees = it) } } }
3. 业务层组合调用
在ViewModel或Repository中整合查询与过滤逻辑:
class ProjectManagerViewModel( private val dao: ProjectManagerDao ) : ViewModel() { fun getFilteredManagers(targetStatus: Int): Flow<List<ProjectManager>> { return flow { val allManagers = dao.getAllProjectManagers() val filteredList = filterProjectManagersByDeviceStatus(allManagers, targetStatus) emit(filteredList) }.flowOn(Dispatchers.IO) } }
性能优化建议
如果未来数据量较大,内存过滤可能带来性能损耗,建议调整数据库结构:
- 将
Employee和Device设为独立数据表,通过外键关联到ProjectManager - 此时可直接通过SQL语句完成过滤,避免内存处理开销:
同时需要修改实体类,添加外键关联,移除原有的SELECT pm.* FROM project_manager pm JOIN employee e ON pm.id = e.project_manager_id JOIN device d ON e.id = d.employee_id WHERE d.status = :targetStatus GROUP BY pm.idTypeConverter。
内容的提问来源于stack exchange,提问作者Rakesh L
相关产品推荐
相关产品推荐

