0

我正在开发一个使用sugarORM 的android 应用程序。我想获得与列表中的 id 匹配的多个项目。

但是,当我打电话时

findWithQuery(A.class, "SELECT * FROM <table> WHERE <column> in (?)", "1,2,3") 

我总是得到一个空列表(尽管我使用 SQLite DB 浏览器仔细检查了查询并且它有效)。

将此查询拆分为多个 findById 似乎效率低下。关于使用 SugarORM 让 WHERE IN 工作的任何想法?

4

2 回答 2

2

经过多次尝试,我发现替换占位符有问题。

从以下切换:

findWithQuery(A.class, "SELECT * FROM <table> WHERE <column> in (?)", "1,2,3")

至:

findWithQuery(A.class, "SELECT * FROM <table> WHERE <column> in (1,2,3)", null)

解决了这个问题。

于 2015-09-24T12:25:24.837 回答
1

问题是 SQLite"1,2,3"会转义参数并将其转换为单个值,然后用于替换?查询字符串中的单个占位符。提供多个参数的正确方法是为每个单独的参数设置一个占位符。然后,您的原始代码行必须更改为:

findWithQuery(A.class, "SELECT * FROM <table> WHERE <column> in (?,?,?)", new String[] { "1","2","3" })

您后来指出,参数的数量是动态的。这可以通过在运行时根据要查询的参数生成查询(特别是 where 子句)来轻松完成。

对于最一般的情况,只需几行代码即可:

final String[] args = new String[] { /* ... */ };
final String query = "SELECT * FROM <table> WHERE <column> in " +
    "(" + TextUtils.join(",", Collections.nCopies(args.length, "?")) + ")";
final List<A> result = A.findWithQuery(A.class, query, args);

(请注意,您可以采取捷径并将参数直接注入查询字符串 - 而不是使用占位符 - 但随后您将失去 SQLite 的内置转义,所以我决定不这样做)

剩下要做的就是String[]从你的论点中产生一个。像这样一个简单的辅助方法应该涵盖大多数场景:

static String[] toStringArray(Object... args) {
    final String[] array = new String[args.length];
    for (int i = 0; i < args.length; i++) array[i] = args[i].toString();
    return array;
}

如果您计划使用原始数组作为参数,您可能希望在其中添加一些null检查并可能设置一些重载。

免责声明:我直接在浏览器中输入了所有内容,因此不能保证一切正常和第一次尝试。:)

于 2015-09-24T15:00:40.043 回答