ORMLite QueryBuilder.orderByRaw(String, SelectArg) 忽略 QueryBuilder.queryRaw() 上的 SelectArg

Posted

技术标签:

【中文标题】ORMLite QueryBuilder.orderByRaw(String, SelectArg) 忽略 QueryBuilder.queryRaw() 上的 SelectArg【英文标题】:ORMLite QueryBuilder.orderByRaw(String, SelectArg) ignores SelectArg on QueryBuilder.queryRaw() 【发布时间】:2020-02-14 01:43:12 【问题描述】:

我有一个新的QueryBuilder<Card, Integer>,我想使用SelectArgorderByRaw

//String column is coming from unknown source
SelectArg selectArg = new SelectArg(SqlType.STRING, column);
qBuilder.selectColumns(column).groupBy(column).orderByRaw("? IS NULL ASC", selectArg);

在此之后我想获得qBuilder.queryRaw()。并且发生了一些非常奇怪的事情。 qBuilder 返回的原始语句是这样的:

SELECT `occupation` FROM `card` GROUP BY `occupation` ORDER BY ? IS NULL ASC

? 在这里没有被替换为 occupation,正如预期的那样,空值首先出现在对象的排序中。

虽然,如果这样做:

qBuilder.selectColumns(column).groupBy(column).orderByRaw(column + " IS NULL ASC");

排序按预期工作(再次使用qBuilder.queryRaw()),空值排在最后,所有内容都按occupation升序排序。

调试

protected abstract void appendStatementEnd(StringBuilder sb, List<ArgumentHolder> argList) throws SQLException;

上述方法将在 argList 中添加 SelectArgs,但随后,queryRaw() 仅使用 preparedStamenteString() 而不是任何 String... arguments 调用,这是很自然的,因为我首先使用这样的方式调用它qBuilder.queryRaw(),导致调用如下方法:

public GenericRawResults<String[]> queryRaw() throws SQLException 
    return dao.queryRaw(prepareStatementString());

我怎样才能使用orderByRaw,而不用担心发生可能的注入?

【问题讨论】:

有趣。你能在单元测试中重现这个吗? 是的。我能够在 JUnit 中重现它。项目在这里:github.com/gogos-venge/ORMlite_JUnit 您能否修改您的测试以显示 data 而不仅仅是查询表单?插入带有和不带有 null 值的 TestObject 中的一个。对他们有什么期望?我已将您的测试复制到我的主人中,但我无法确定正确的结果应该是@verge。 是的。我刚刚推出了一个带有一些模型的新测试。 5 个单词和 5 个空值。使用orderByRaw("? IS NULL ASC", selectArg) 首先给出一个空值的结果,而orderByRaw("testColumn IS NULL ASC") 最后给出一个空值的结果。 orderByRaw("testColumn IS NULL DESC") 会给出一个空值在前的结果。 为了更加清晰,我做了一些更改:appendList 现在是 implodeList,而且我在 ormlite.Logger.info 中包含了一个简单的选择查询来显示数据库内容。请考虑再次克隆! 【参考方案1】:

我真的不认为这是一个错误@venge。您的测试验证了查询字符串,但 ? 扩展为字符串 "testColumn" 发生在执行查询时,因此不会在那里扩展。您可以打开日志记录以查看是否正在运行正确的查询。如果不是这样,我们会看到没有列名 ? 或没有指定 ? 的参数的问题。

2019-11-01 18:15:16,761 [TRACE] BaseMappedStatement 准备好的语句参数:[testColumn] 2019-11-01 18:15:16,781 [DEBUG] 'SELECT testColumn FROM testobject GROUP BY testColumn ORDER BY 的 StatementExecutor 查询? IS NULL ASC ' 返回 4 个结果

我认为这里的问题是ORDER BY ... IN NULL ASC。在阅读有关在那里使用 NULL 的文档时,我对它应该做什么感到困惑。 ASCDESC 似乎不会影响我测试中的排序顺序。

【讨论】:

ORDER BY ... IS NULL ASC 应该返回一个结果,其中空值在排序顺序中排在最后,而ORDER BY ... IS NULL DESC 应该在排序顺序中将空值放在首位。其余的值似乎不受影响。我在 SQLite 编辑器和我刚刚推送的 JUnit 测试的模型数据中都确认了这一点。 ORDER BY 子句中的列名? 而言,它似乎完全有效。 ? 我认为是个小丑角色。我刚刚在 SQLite 编辑器中做了一个SELECTSELECT address FROM card GROUP BY address ORDER BY ? IS NULL ASC,它没有抱怨。

以上是关于ORMLite QueryBuilder.orderByRaw(String, SelectArg) 忽略 QueryBuilder.queryRaw() 上的 SelectArg的主要内容,如果未能解决你的问题,请参考以下文章

android ORMlite的应用

Android—Ormlite框架简单的操作数据库

如何在 android 中使用 ProGuard 和 OrmLite

ServiceStack.OrmLite 调用存储过程

ORMLite 中的集合

android OrmLite 入门