SugarORM findWithQuery 和 WHERE IN

SugarORM findWithQuery and WHERE IN

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

然而当我打电话给

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

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

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

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

切换自:

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)

修复了问题。

问题是 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 检查并可能设置一些重载。

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