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 上的错误,还是我做错了什么?

4

4 回答 4

13

怎么了

您可以作为参数传递给@Dao方法的唯一值是值,而不是查询字符串。这样做的原因(我相信)是为了防止 SQL 注入问题。

为什么会这样

例如查询SELECT * emails WHERE uid = ?然后将值设置为"1 OR WHERE isAdmin = true". 这将允许人们在您的数据库上运行他们自己的定制查询并做他们想做的事。

我的解决方案

我也遇到了这个问题。这是我的解决方案的链接。

我的解决方案有 2 个部分。首先DynamicQueryservice根据输入生成查询字符串和值数组,然后运行原始查询并返回一个Cursor. 其次,一个Cursor2POJO映射器,因此我不必一遍又一遍地为类写出游标映射,也不必引入潜在的维护问题。我只是向我的类添加注释(与房间列名匹配),其余部分由 lib 处理。

为了您的利益,我已将我的光标映射器分离到它自己的中,请随意使用它(如果自述文件不清楚,或者在评论中有错误击中我,请随意使用它)。

PS 我的库无法使用 Room @ColumnInfo 获取列名,因为注释当前设置为 RetentionPolicy.CLASS,因此无法通过反射访问。(添加到 Google 问题跟踪器https://issuetracker.google.com/issues/63720940

于 2017-07-15T10:21:56.117 回答
12

如果您尝试按字符串字段排序,那么您可能会遇到字符串大小写问题,那么您应该尝试使用LOWER(your_string_field_name)UPPER(your_string_field_name) 如下所示:

@Query("SELECT * FROM User ORDER BY LOWER(name) ASC"

享受编码:)

于 2020-01-20T07:29:20.890 回答
11

您应该使用@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));
于 2018-11-27T07:24:06.113 回答
1

您只能参考任何列的名称按升序排列数据。以编程方式,您不能将任何值传递给 Dao 方法

于 2018-05-27T17:47:18.373 回答