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
检查并可能设置一些重载。
免责声明:我在浏览器中直接输入了所有内容,因此不能保证一切正常并且是第一次尝试。 :)
我正在开发一个使用 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
检查并可能设置一些重载。
免责声明:我在浏览器中直接输入了所有内容,因此不能保证一切正常并且是第一次尝试。 :)