Room DAO查询优化:优先匹配Code字段再匹配Name字段的实现
解决Room DAO中优先匹配code字段的查询需求
要实现优先返回code字段匹配的结果,只有当code无匹配时才返回name字段匹配的结果,你需要调整查询的优先级逻辑,以下是两种可行方案:
方案一:通过排序规则强制code匹配结果靠前
给查询结果添加排序优先级,让匹配code的记录排在最前面,结合LIMIT就能优先获取code匹配的结果。修改后的DAO代码如下:
@Query(""" SELECT code, name FROM RoomStations WHERE :input IS NULL OR LOWER(code) LIKE LOWER(:input) OR LOWER(name) LIKE LOWER(:input || '%') ORDER BY -- 匹配code的记录优先级设为1,其余为2,确保code结果优先展示 CASE WHEN LOWER(code) LIKE LOWER(:input) THEN 1 ELSE 2 END, code ASC LIMIT 3 """) fun getStations(input: String?): List<RoomStation>
当输入BE时,BE-BAREILLY会因匹配code被标记为高优先级,直接排在结果首位,LIMIT 3会优先选取这类记录,不会被name匹配的结果抢占位置。
方案二:用UNION拆分查询,先查code再查name
通过UNION ALL合并两个独立查询:先获取code匹配的记录,再获取name匹配且未出现在code结果中的记录,彻底保证code匹配结果的优先级。代码如下:
@Query(""" -- 优先查询code匹配的记录 SELECT code, name FROM RoomStations WHERE :input IS NULL OR LOWER(code) LIKE LOWER(:input) UNION ALL -- 仅查询name匹配但code不匹配的记录(排除已在code结果中的项) SELECT code, name FROM RoomStations WHERE :input IS NOT NULL AND LOWER(name) LIKE LOWER(:input || '%') AND code NOT IN ( SELECT code FROM RoomStations WHERE LOWER(code) LIKE LOWER(:input) ) LIMIT 3 """) fun getStations(input: String?): List<RoomStation>
这种方式逻辑更严谨,当存在code匹配结果时,name匹配的结果只会返回code完全不匹配的记录,避免两种结果混排。
原查询问题说明
你之前的查询用OR连接两个匹配条件,所有满足code或name匹配的记录都会被检索,但因为未指定ORDER BY,数据库会按默认存储顺序返回结果,导致BE-BAREILLY可能排在name匹配的结果之后,被LIMIT截断。
内容的提问来源于stack exchange,提问作者Pawandeep Singh
相关产品推荐
相关产品推荐

