Указание ограничения/смещения для запросов ContentProvider
Я пытаюсь заставить ContentResolver запустить этот запрос:
select * from myTable limit 1 offset 2
В ContentResolver единственный метод запроса:
resolver.query(uri, projection, selection, selectionArgs, sortOrder);
Я пробовал:
final Cursor c = resolver.query(
MyTable.CONTENT_URI,
MyTable.PROJECTION,
" ? ?",
new String[] {"1", "2"},
null);
Это просто выбрасывает исключение IllegaLArgumentException.
Каков правильный способ достижения этого?
Ответы
Ответ 1
Я помещаю предложение LIMIT в параметр sordOrder, я также видел то же самое, что делали другие, но не уверен, что его 100% правильно:
final Cursor c = resolver.query(
MyTable.CONTENT_URI,
MyTable.PROJECTION,
null,
null,
" limit 1 offset 2");
Ответ 2
Если вы предоставляете свой контент-провайдер, вы можете использовать android.net.Uri.Builder#appendQueryParameter
для предоставления лимита и смещения в качестве параметров запроса, содержание которых провайдер может использовать при построении запроса.
public class MyProvider extends ContentProvider {
public static final String QUERY_PARAMETER_LIMIT = "limit";
public static final String QUERY_PARAMETER_OFFSET = "offset";
public Cursor query(Uri uri, ...) {
String limit = uri.getQueryParameter(QUERY_PARAMETER_LIMIT);
String offset = uri.getQueryParameter(QUERY_PARAMETER_OFFSET);
SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
// set the table name,...
// leaving handling of null conditions as an exercise to the reader.
String limitString = offset + "," + limit;
Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, sortOrder, limitString);
//...
return c;
}
}
при построении запроса:
private static final Uri CONTENT_URI = MyProvider.CONTENT_URI.buildUpon()
.appendQueryParameter(MyProvider.QUERY_PARAMETER_LIMIT,
String.valueOf(limit))
.appendQueryParameter(MyProvider.QUERY_PARAMETER_OFFSET,
String.valueOf(offset))
.build();
обратите внимание, что android.net.Uri.Builder#appendQueryParameter
кодирует значение, чтобы предотвратить SQL-инъекцию.
Ссылки:
Ответ 3
Я помещаю предложение limit в качестве параметра запроса, используя синтаксис 'limit = offset, limit':
Cursor c = context.getContentResolver().query(
MyTable.CONTENT_URI.buildUpon().encodedQuery("limit="+offset+","+limit).build(),
MyTable.PROJECTION,
null,
null,
null);
Он работает, по крайней мере, с помощью MediaStore uris. Будьте осторожны, не кодируя ",", или он не будет работать.
Ответ 4
Когда я попытался использовать предел String [см. предельную строку ниже], используя следующее:
StringBuilder sbLimit = new StringBuilder().append(" ").append(i_offset).append(" , ").append(i_limit);
String limit = sbLimit .toString()
Это дало мне хорошие результаты в сочетании с выборами запросов, сортировкой и группировкой.