SQLiteQueryBuiler.setProjectionMap()不影响where子句

时间:2015-02-05 07:47:27

标签: android sql sqlite

我有一个带有ContentProvider类的Android应用,可以查询两个表usersitems

users表包含以下列:

_id (primary key)
online (integer)

items表包含以下列:

_id (primary key)
user_id (foreign key, maps to users._id)
name (text)

然后我有一个查询返回连接在一起的两个表的结果。在我的ContentProvider中,我使用此代码映射列名称:

SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
queryBuilder.setTables("items INNER JOIN users ON users._id=items.user_id"); 
Map<String, String> columnMap = new HashMap<String, String>();
columnMap.put("item_id", "items._id");
columnMap.put("user_id", "items.user_id");
columnMap.put("user_online", "users.online");
columnMap.put("item_name", "items.name");
queryBuilder.setProjectionMap(columnMap);

但是,当我执行以下查询时,要查找在线用户拥有的所有项目:

String[] projection = {"item_name"};
String selection = "user_online=1";
Cursor cursor = getContentResolver().query(uri, projection, selection, null, null);

我得到以下异常:

android.database.sqlite.SQLiteException: no such column: user_online (code 1): , while compiling: SELECT items.name FROM items INNER JOIN users ON users._id=items.user_id WHERE (user_online=1)

问题似乎是setProjectionMap()影响projection,而不影响selection

是否还有其他方法可以解决此问题,而不是在投影上执行字符串操作以手动映射列名称?

1 个答案:

答案 0 :(得分:2)

仅需要

setProjectionMap,因为它允许查询的输出列名称。

在选择中执行的操作在结果游标中不可见,并且在任何情况下SQLiteQueryBuilder都不够智能,无法解析SQL并替换正确的列名。

只需使用原始列名:

String selection = "users.online=1";

要在选择中提供列别名,请为您的联接创建一个视图:

CREATE VIEW user_items AS
SELECT items._id AS item_id,
       items.user_id AS user_id,
       users.online AS user_online,
       items.name AS item_name
FROM items INNER JOIN users ON users._id=items.user_id;