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