Android会议室:订单不工作

我正在使用新的Android ORM Room。 我遇到了问题。 带参数的ORDER BY不起作用。 如果我想使用ORDER BY参数中的字段,则无效。 没有任何吸引力。

@Query("SELECT * FROM User ORDER BY :orderBY ASC") List sortedFind(String orderBY); 

但是,当我直接将哪个字段排序然后它按预期工作。

 @Query("SELECT * FROM User ORDER BY name ASC") List sortedFind(); 

它是android Room上的bug,还是我做错了什么?

Solutions Collecting From Web of "Android会议室:订单不工作"

发生什么事

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

为什么会这样

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

我的解决方案

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

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

为了你的利益,我已经将我的Cursor映射器分离到它自己的库中,随意使用它(如果自述文件不清楚,或者在评论中有错误,我就这样做了)。

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

问题是你想要传递一部分SQL语句,但是Room会将它视为查询参数。

如果你想要,你可以尝试使用Kripton Persistence Library,这是一个开源库,SQLite的Android平台管理和支持你提到的情况。

Kripton也使用DAO模式,因此概念非常相似。 只是写一个符合您需求的示例:

给定一个模型类:

 @BindType public class User { public long id; public String name; public String username; public String email; public Address address; public String phone; public String website; public Company company; } 

DAO定义:

 @BindDao(User.class) public interface UserDao { @BindSqlInsert void insert(User bean); @BindSqlSelect List sortedFind(@BindSqlDynamicOrderBy String orderBy); } 

和数据源定义:

 @BindDataSource(daoSet={UserDao.class}, fileName = "kripton.quickstart.db", generateAsyncTask = true) public interface QuickStartDataSource { } 

Kripton将在编译时生成所有需要与数据库一起工作的代码。 因此,要使用Kripton完成任务,您必须编写类似于以下内容的代码:

 BindQuickStartDataSource ds = BindQuickStartDataSource.instance(); // execute operation in a transaction ds.execute(new BindQuickStartDataSource.SimpleTransaction() { @Override public boolean onExecute(BindQuickStartDaoFactory daoFactory) throws Throwable { UserDaoImpl dao = daoFactory.getUserDao(); dao.sortedFind("name asc"); return true; } }); 

在logcat中执行上面的代码时,您将看到生成的日志:

 database OPEN READ_AND_WRITE_OPENED (connections: 1) SELECT id, name, username, email, address, phone, website, company FROM user ORDER BY name asc Rows found: 0 database CLOSED (READ_AND_WRITE_OPENED) (connections: 0) 

Kripton显然也支持静态秩序和许多其他function(我在2015年开始开发它)。

有关Kripton持久性库的更多信息:

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