rawQuery в ContentProvider

В процессе написания программы возникла необходимость выполнить к базе данных сложный запрос, с кучей JOIN и условий. При прямой работе с БД достаточно было использовать rawQuery(queryText, params), однако я использовал в своей программе контент-провайдер, дабы соответствовать высоким стандартам google )))

Оказалось, что контент-провайдеры не предназначены для таких выкрутасов, ибо стандартный метод контент-провайдера query() выглядит так:

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

Т.е. передать в него просто так произвольный запрос проблематично. Использовать прямую работу с БД не хотелось, так что выход из ситуации нашелся и довольно быстро. Приведу кусочек своего контент-провайдера и его метода query() :


static final String AUTHORITY = "ru.droidtips.providers.demo1"; // Authority контент-провайдера
static final String MYTABLE_PATH = "mytable"; // путь к таблице mytable базы данных
static final String RAW_QUERY_PATH = "raw";   // А это - путь к произвольному запросу.

// Uri контент-провайдера
public static final Uri MYTABLE_CONTENT_URI = Uri.parse("content://"
    + AUTHORITY + "/" + MYTABLE_PATH); // content://ru.droidtips.providers.demo1/mytable - запрос к таблице mytable

public static final Uri RAW_URI = Uri.parse("content://"
    + AUTHORITY + "/" + RAW_QUERY_PATH); // content://ru.droidtips.providers.demo1/raw - произвольный запрос к базе данных

// UriMatcher
static final int URI_MYTABLE = 1; // общий Uri
static final int URI_MYTABLE_ID = 2; // Uri с указанным ID
static final int URI_RAW_QUERY = 3; // Uri произвольного запроса

// описание и создание UriMatcher
private static final UriMatcher uriMatcher;
static {
	uriMatcher.addURI(AUTHORITY, MYTABLE_PATH, URI_MYTABLE);
	uriMatcher.addURI(AUTHORITY, MYTABLE_PATH + "/#", URI_MYTABLE_ID);
	uriMatcher.addURI(AUTHORITY, RAW_QUERY_PATH, URI_RAW_QUERY);
}

@Override
public Cursor query(Uri uri, String[] projection, String selection,
 String[] selectionArgs, String sortOrder)
{
    // Проверяем тип Uri, и если Uri содержит RAW_QUERY - то делаем произвольный запрос
    switch (uriMatcher.match(uri))
    {
    [...]
    case RAW_QUERY:
        return dbHelper.getReadableDatabase().rawQuery(selection, selectionArgs);
    }
    [...]
}

Смысл простой:  передаем контент-провайдеру null вместо описания столбцов(projection), сам запрос в поле selection, а параметры запроса, если они есть, в поле selectionArgs. Если Uri, переданный контент-провайдеру соответствует произвольному запросу, то мы его выполняем, используя в качестве запроса поле selection и selectionArgs — в качестве его параметров.

Таким образом, вызов контент-провайдера может быть, например, таким:

	String query = "SELECT * FROM mytable WHERE _id > ? LIMIT 100";
	String[] arguments = new String[] {"123"};

	// создаем CursorLoader
	CursorLoader(this, RAW_URI, null, query, arguments, null);

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *