Android 为ContentProvider查询指定限制/偏移量

Android 为ContentProvider查询指定限制/偏移量,android,android-contentprovider,Android,Android 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.

我正在尝试让我的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);
这只是抛出了一个非法的辩论例外。
实现这一点的正确方法是什么?

我将LIMIT子句放在sordOrder参数中,我也看到其他人做了同样的事情,但不确定它是否100%正确:

final Cursor c = resolver.query(
        MyTable.CONTENT_URI,
        MyTable.PROJECTION,
        null,
        null,
        " limit 1 offset 2");

我使用“limit=offset,limit”语法将limit子句作为查询参数:


它至少适用于MediaStore URI。请注意不要对“,”进行编码,否则它将不起作用。

如果您提供内容提供商,则可以使用提供限制和偏移量作为查询参数,内容提供商可以在生成查询时使用这些参数

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();
注意,对值进行编码以防止sql注入

参考资料:
  • +

  • 当我尝试使用限制字符串[参见下面的限制字符串]时,使用以下命令:

     StringBuilder sbLimit = new StringBuilder().append(" ").append(i_offset).append(" , ").append(i_limit);
    String limit = sbLimit .toString()
    

    这与select查询、排序和分组相结合,给了我很好的结果。

    谢谢。实际上,我曾经尝试过使用它,但认为它不起作用,因为SQLQueryBuilder源代码版本已经过时。。现在开始工作。欢迎您,因为您与内容提供商合作,我有一个无耻的插件!我正在开发一个开源DSL,它可以轻松编写和维护sqlite支持的内容提供商,具体说明请访问父页面以获取安装说明,虽然我会警告它的alpha值,但它仍然可能是有趣的:)否则该子句将被错误地附加到基础查询中,导致无效的SQL语句这对Android 11不起作用,
    java.lang.IllegalArgumentException:invalid token limit
    不确定开发人员为什么会称之为“滥用”,
    //一些应用程序滥用“ORDER BY”子句来注入“LIMIT”
    ,感谢您提供替代解决方案,但我现在已经解决了这个问题:这比公认的答案好多了。排序顺序中的Piggy backing限制是一个可怕的黑客行为,很容易破坏提供程序的实现。相关:相关:你已经晚了几年,我也无法验证这是否有效,但感谢你详细的回答,我希望这对某人有所帮助@Buffalo,我在我的应用程序中使用这段代码,我在这里写这段代码的部分原因是,我可以稍后回来,以防我“失去”对这段代码的访问。android中有太多的东西需要记住。我最喜欢这种方法,但似乎limit和offset是相反的,所以构建limitString应该写为:limitString=offset+“,”+limit@nicolai,谢谢您的注意,我已将答案更新为不那么模棱两可。@Avinash是的,但该语法无效。我试过了,它给出了
    java.lang.IllegalArgumentException:invalid LIMIT子句:LIMIT 10
    ,因为它接受偏移量、限制模式。请参见SQLiteQueryBuilder源代码中的第208行和第40行。限制字符串的正则表达式为“\\s*\\d+\\s*(,\\s*\\d+\\s*)?”,但不匹配
     StringBuilder sbLimit = new StringBuilder().append(" ").append(i_offset).append(" , ").append(i_limit);
    String limit = sbLimit .toString()