Могу ли я выполнить этот запрос Android с ContentResolver.query ()? (СЛЕДУЕТ ПРИСОЕДИНЯТЬСЯ И ДЕЛАТЬ) - PullRequest
20 голосов
/ 14 июня 2011

Я хочу выполнить следующий запрос (в псевдокоде) на Android:

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 = ?

Я ищу, чтобы выбрать идентификатор и имя ВСЕХ контактов в системной адресной книге через ContentProvider контактов по умолчанию, а также Поле 0/1, указывающее, является ли контакт членом группы ?.

Конечно, я мог бы достаточно легко получить все контакты, затем выполнить цикл и запросить членство по отдельности достаточно легко в моем классе Adapter, но я представляю, что выполнение этих двух запросов в виде одного запроса с внешним соединением даст гораздо лучшую производительность.

Могу ли я сделать это с помощью стандартного высокоуровневого проецирования строк и метода ContentResolver.query()? Или этот тип запроса требует более непосредственного выполнения SQL?

Ответы [ 3 ]

41 голосов
/ 01 июля 2011

Редактировать: Хорошо, так что это фактически не решает заданный вопрос, потому что eidylon привязан к существующему ContentProvider, как упомянуто в их вопросе.Однако, это действительно касается того, как вы выполняете JOIN, если у вас есть источник и API ContentProvider.Поэтому я оставлю это для тех, кто хочет знать, как обращаться с этим делом.


Это просто!Но не интуитивно понятно ...:)

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 вы можете получить необработанный доступ к вашей базе данных SQLite, не ограниченный ограниченной моделью данных query().Не стесняйтесь использовать его!

Определите поля выбора, как вам нравится.У них нет для сопоставления с именами столбцов таблицы - сопоставьте их так, как вам нужно, чтобы получить ваши параметры.

Определите свою проекцию так, как вам нужно - это можетсодержать столбцы из обеих таблиц после объединения.

Bing, все готово.Google делает эту же модель внутренне в своем собственном коде - посмотрите на API провайдера контактов - вы видите «bla.RawContact» и «bla.Contact» и т. Д. В качестве URI контента.Каждый обслуживает данные из одной и той же таблицы в БД - разные URI просто предоставляют разные представлений этой же таблицы!

7 голосов
/ 27 июня 2011

Нет, вы не можете делать такие запросы с помощью метода 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 голосов
/ 30 июня 2011

Вы не можете сделать это, потому что ContentResolver имеет только один метод запроса:

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

нет параметров для таблиц или предложений FROM.

...