我的SQLite
数据库中有一个表:
种类:
_id | species | description
---------------------------
1 | Aardvark | Some description for Aardvark
2 | Aardwolf | Some description for Aardwolf
3 | Caracal | Some description for Caracal
我从服务器收到ID列表,我只想显示与我收到的ID对应的种类。
现在我知道一些选择:
1.一种明显而幼稚的方式是:
SQLiteDatabase db = this.openDatabase();
for (int id : idList) {
Cursor cursorSpecies = db.query(true, TABLE_SPECIES, new String[] {COL_SPECIES_SPECIES},
COL_ID + "=?", id, null, null, null, null);
cursorSpecies.moveToNext();
speciesList.add(cursorSpecies.getString(0));
cursorSpecies.close();
}
这将执行太多的操作,并且我假设读取多个小“磁盘”,这将非常慢。
2.另一个选择是使用SQLiteStatement,但这仅返回一个值,无论如何对于我的示例和shouldn't really be used for queries都无效。
3.另一个选择是将条件手动连接到原始的
SQL
查询中,大致类似于:SQLiteDatabase db = this.openDatabase();
String query = "SELECT * FROM " + TABLE_SPECIES + " WHERE ";
for (int id : idList) {
query += COL_ID + "=" + id + " OR ";
}
// I am aware this will end in an " OR" but this is not the point of this example so please ignore it.
Cursor cursorSpecies = db.rawQuery(query, null);
// Use the cursor and close it.
While this should work decently well, a very large query would probably break some query string length limit so this is not ideal either.
所有这些示例都可以在一定程度上起作用,但是它们都有陷阱。不知何故,我觉得我缺少解决方案,因此提出了一个问题:
执行这类查询的正确方法是什么?
谢谢。
最佳答案
对于问题中的特殊情况,仅考虑WHERE id IN (x,y,z, ...)
。
要在标题中解决问题,而不仅仅是问题正文中的特殊情况:
在这方面,Android SQLite API并不是很通用。
在原始sqlite3 C API中,可以通过单个sqlite3_prepare*()
调用来获得sqlite3_statement
并将其绑定到位,使用sqlite3_step()
来获取行,然后重置该语句以将其与新的参数绑定一起重用。
在Android API中,该语句对应于Cursor
,而步进等效于移动光标。重置和重新绑定功能仅在SQLiteCursor
中以requery()
和setSelectionArguments()
的形式提供。
因此,请尝试以下方法:
使用选择参数进行常规查询。
假定默认光标工厂,将结果Cursor
强制转换为SQLiteCursor
。
访问您需要的行。
用setSelectionArgs()
更新选择参数requery()
转到3,除非完成