Android Studio中Room结合SQLite如何编写带排序参数的查询?
实现Room查询支持多字段动态排序
已知通过以下Code A实现了带id参数的SQLite查询,现需要修改Code B,使其支持按createdDate升序/降序、title升序/降序四种排序方式。
原Code A
@Query("SELECT * FROM info_table where id=:id") suspend fun getByID(id: Int): RecordEntity
原Code B
@Query("SELECT * FROM info_table ORDER BY createdDate desc") fun listAll(): Flow<List<RecordEntity>>
解决方案
由于Room不允许直接将排序字段名作为参数传入(会被解析为字符串常量导致排序失效),同时为了避免SQL注入风险,推荐使用枚举约束输入+CASE WHEN映射字段的方式实现:
1. 定义枚举类约束合法的排序字段和方向
// 排序字段枚举,限制只能选择createdDate或title enum class SortField { CREATED_DATE, TITLE } // 排序方向枚举,限制只能选择升序或降序 enum class SortDirection { ASC, DESC }
2. 修改Code B的查询方法
@Query(""" SELECT * FROM info_table ORDER BY CASE :sortField WHEN 'CREATED_DATE' THEN createdDate WHEN 'TITLE' THEN title END COLLATE NOCASE :sortDirection """) fun listAll(sortField: SortField, sortDirection: SortDirection): Flow<List<RecordEntity>>
3. 调用示例
// 按createdDate升序查询 val ascendingCreatedDateFlow = listAll(SortField.CREATED_DATE, SortDirection.ASC) // 按title降序查询 val descendingTitleFlow = listAll(SortField.TITLE, SortDirection.DESC)
说明
COLLATE NOCASE用于忽略大小写排序(如果不需要可以去掉)- 枚举类确保了传入的排序字段和方向只能是合法值,避免了非法输入导致的SQL语法错误或注入风险
- 如果不需要严格约束,也可以直接传递字符串参数(但需自行保证传入值为
createdDate/title和ASC/DESC)
内容的提问来源于stack exchange,提问作者HelloCW
相关产品推荐
相关产品推荐

