19

我期待执行下面的查询(在伪代码):我可以使用ContentResolver.query()来执行此Android查询吗?在Android(LEFT JOIN和CASE)

SELECT C.ID, C.NAME, CASE ISNULL(G.GROUPID,0) = 0 THEN 0 ELSE 1 END INGROUP 
FROM CONTACTS C 
LEFT JOIN GROUPMEMBERSHIP G ON G.CONTACTID = C.ID AND G.GROUPID = ? 

我期待选择系统中的地址簿中的所有联系人的标识和名称,通过默认的联系人内容提供者,以及指示联系人是否为?组成员的 0/1字段。我可以很容易地获得所有的联系人,然后在我的Adapter类中分别循环查询各个成员资格,但我想象执行这两个查询作为一个外部联接查询会产生更好的性能。

我可以用标准的高级别字符串投影和ContentResolver.query()方法来做到这一点吗?或者这种查询是否需要挖掘更直接的SQL执行?

回答

7

不,你不能用ContentResolver.query()方法做这种查询。 你需要写的东西是这样的:

SQLiteDatabase db = YourActivity.getDbHelper().getReadableDatabase(); 
String query = yourLongQuery; 
Cursor c = db.rawQuery(query, null); 
YourActivity.startManagingCursor(c); 
c.setNotificationUri(YourActivity.getContentResolver(), YourContentProvider.CONTENT_URI); 
+0

从四处搜索,我得到的印象是,您不能使用SQLLiteDatabase查询其他应用程序......在我的情况下是CONTACTS uri,但仅用于查询您自己的数据存储区。它是否正确?在这种情况下,我想我会在绑定我的活动时停留在我的Adapter类中执行子查询。 – eidylon 2011-06-27 17:10:18

+0

@eidylon:我不知道你在查询联系人数据库。是的,你是对的:( – Macarse 2011-06-27 17:45:36

+0

Drat!噢,以及...向上和向上!谢谢! – eidylon 2011-06-27 20:58:17

0

你不能这样做,因为ContentResolver的只有一个查询方法:

query(Uri uri, String[] projection, String selection, 
String[] selectionArgs, String sortOrder) 

有表或FROM子句中没有参数。

41

编辑:好了,所以这实际上并没有解决问题的要求,因为在他们的问题中提到eidylon被绑定到现有的ContentProvider。但是,如果您拥有ContentProvider源和API,则会涵盖如何执行JOIN。所以我会把它留给那些想知道如何处理这种情况的人。


这很简单!但不直观... :)

query(Uri uri, String[] projection, String selection, 
String[] selectionArgs, String sortOrder) 

好的,那么什么是URI?通常,每个表有一个URI。

content://com.example.coolapp.contacts向您的CONTACTS表提供数据。 content://com.example.coolapp.groupmembers为您的GROUPMEMBERSHIP表提供数据。

但是URI实际上只是一个字符串。不管你喜欢用它。在您的ContentProvider中创建一个代码块,以响应content://com.example.coolapp.contacts_in_group。在ContentProvider中的这段代码中,您可以不受有限的query()数据模型的限制,获得对SQLite数据库的原始访问权限。随意使用它!

无论你喜欢如何定义你的选择字段。他们不映射到表列名 - 映射他们你需要如何,为了得到你的参数英寸

定义你的投影你需要 - 它可能包含两个表后列加入。

必应,你完成了。 Google在自己的代码中内部执行相同的模型 - 查看联系人提供程序API - 您将“bla.RawContact”和“bla.Contact”等视为内容URI。每个服务器都在数据库中的同一个表中提供数据 - 不同的URI只提供同一个表的不同视图

+0

感谢你的回答...这是非常详细的和内容丰富的,所以我upvoted;但显然***是我***我的Q不清楚我是在查询Android Contacts db,而不是我自己的db。你不是唯一一个错过了这个的人,我已经更新了我的措辞,以便更清楚一点。谢谢!:) – eidylon 2011-07-03 02:19:02

+1

对不起,是的。如果您使用的是现有的contactProvider,那么您会遇到任何内容URI和他们实施的联接。 – jcwenger 2012-02-10 14:10:25

+0

所以总结一下,在你的ContentProvider中,重写“查询”方法,检查你的URI,并做任何你想要的与SQLite数据库的直接连接?谢谢! – 2013-05-10 20:14:45