Android Room:按不工作排序
Posted
技术标签:
【中文标题】Android Room:按不工作排序【英文标题】:Android Room: Order By not working 【发布时间】:2017-10-29 16:03:48 【问题描述】:我正在使用新的 android ORM Room。 我遇到了以下问题,使用带有参数的 ORDER BY 的查询不起作用。
如果我想使用从 ORDER BY 的参数填充的字段,它不起作用。它只是不排序任何东西。
@Query("SELECT * FROM User ORDER BY :orderBY ASC")
List<User> sortedFind(String orderBY);
但是,当我将 ORDER BY 列直接放在查询中以对结果进行排序时,它会按预期工作。
@Query("SELECT * FROM User ORDER BY name ASC")
List<User> sortedFind();
这是 Android Room 的错误,还是我做错了什么?
【问题讨论】:
向谷歌举报issuetracker.google.com/issues/62169706 我的猜测是他们不希望查询的那部分是可变的。 AFAIK,如果您在没有 Room 的情况下直接使用 SQLite,SQLite 也不支持SELECT * FROM User ORDER BY ? ASC
。
@CommonsWare 是的。有道理。。谢谢回复。
为了避免编写多个查询,这将是 Room 中的一个很棒的功能。
【参考方案1】:
发生了什么
您可以作为参数传递给@Dao
方法的唯一值是值,而不是查询字符串。这样做的原因(我相信)是为了防止 SQL 注入问题。
为什么会这样
例如查询SELECT * emails WHERE uid = ?
,然后将值设置为"1 OR WHERE isAdmin = true"
。这将允许人们在您的数据库上运行他们自己的定制查询并做他们想做的事情。
我的解决方案
我也遇到了这个问题。这是我的solution 的链接。
我的解决方案有 2 个部分。首先DynamicQueryservice
根据输入生成查询字符串和值数组,然后运行原始查询并返回Cursor
。其次,Cursor2POJO
映射器,因此我不必一遍又一遍地为类写出游标映射,也不必引入潜在的维护问题。我只是为我的类添加注释(与房间列名匹配),其余部分由 lib 处理。
为了您的利益,我已经将我的光标映射器分成了自己的library,请随意使用它(如果自述文件不清楚,或者在 cmets 中遇到错误,请随意使用它)。
附:我的库无法使用 Room @ColumnInfo 获取列名,因为注释当前设置为 RetentionPolicy.CLASS,因此无法通过反射访问。 (添加到 Google 问题跟踪器 https://issuetracker.google.com/issues/63720940)
【讨论】:
无法传递查询字符串的原因更有可能是我们将失去查询的编译时安全性——这是 Room 的基本优势。 出于安全目的不允许将参数用于 ORDER BY 听起来完全是蹩脚。【参考方案2】:您只能根据任何列的名称按升序排列数据。 以编程方式,您不能将任何值传递给 Dao 方法
【讨论】:
【参考方案3】:您应该使用@RawQuery
注释和SupportSQLiteQuery
类进行运行时查询
在道:
@RawQuery
List<Objects> runtimeQuery(SupportSQLiteQuery sortQuery);
获取数据:
String query ="SELECT * FROM User ORDER BY " + targetField + " ASC";
List<Objects> users = appDatabase.daoUser().runtimeQuery(new SimpleSQLiteQuery(query));
【讨论】:
【参考方案4】:如果您尝试按字符串字段排序,那么您可能会遇到字符串大小写问题, 那么你应该尝试使用 LOWER(your_string_field_name) 或 UPPER(your_string_field_name) 如下:
@Query("SELECT * FROM User ORDER BY LOWER(name) ASC"
享受编码:)
【讨论】:
以上是关于Android Room:按不工作排序的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 DISTINCT 和 UNION 按不区分大小写的 ASC 或 DESC 排序
Android Room Embedded Field 未编译