3

我有一个关于使用内容提供者实现复杂查询的最佳实践的问题。正如我从 android 联系人内容提供商看到的,建议使用字段selectionselectionArgs等来发出特定请求。

我现在正在塑造我的第一个自己的内容提供商。它背后有一个相当复杂的野兽,带有规范化表的数据库的所有连接、全文表等结构。当然,我想对内容提供者的用户隐藏这种复杂性,但我只是还不知道如何实现它。如果用户使用selectionselectionArgs等指定他的请求,内容提供者似乎必须解析这些并将其映射到底层结构。是否有一些用于此解析的工具,或者我最终会编写自己的选择字符串解析器等。

恐怕这是要走的路,但在实施之前,我想听听周围 android 专业人士的一些建议。

非常感谢

马丁

4

1 回答 1

0

这就是我现在所处的位置,至少我想快速分享一些解决方案,以获得鼓舞人心的专家反馈,并可能为周围的其他血腥新手提供一些提示。一开始我的基本错误似乎是没有引入内容提供商向其用户提供的“虚拟”数据库之类的层。一旦完成,隐藏背后的复杂性并且可以使用查询的正常语法。

所以我所做的是在内容提供者合同类中有一个“虚拟”数据库层,

public class JustDharmaQuotesContract {

public class Quote {

    public static final String TABLE_NAME = QuoteTable.TABLE_NAME;

    public static final String _ID = TABLE_NAME + "." + QuoteTable._ID;
    public static final String AUTHOR = TABLE_NAME + "." + QuoteTable.AUTHOR;
    public static final String AUTHOR_FULL_NAME = TABLE_NAME + "." + QuoteTable.AUTHOR_FULL_NAME;
    public static final String TITLE = TABLE_NAME + "." + QuoteTable.TITLE;
    public static final String QUOTE = TABLE_NAME + "." + QuoteTable.QUOTE;
    public static final String QUOTE_LENGTH = TABLE_NAME + "." + QuoteTable.QUOTE_LENGTH;
    public static final String BLOG_POST_LINK = TABLE_NAME + "." + QuoteTable.BLOG_POST_LINK;
} 

public class QuoteFTS {

    public static final String TABLE_NAME = QuoteFtsTable.TABLE_NAME;

    public static final String _ID = TABLE_NAME + "." + QuoteFtsTable._ID;
    public static final String TITLE = TABLE_NAME + "." + QuoteFtsTable.TITLE;
    public static final String QUOTE = TABLE_NAME + "." + QuoteFtsTable.QUOTE;
    public static final String SNIPPET = "snippet";

    public static final String AUTHOR = Quote.TABLE_NAME + "." + QuoteTable.AUTHOR;
    public static final String AUTHOR_FULL_NAME = Quote.TABLE_NAME + "." + QuoteTable.AUTHOR_FULL_NAME;
    public static final String QUOTE_LENGTH = Quote.TABLE_NAME + "." + QuoteTable.QUOTE_LENGTH;
    public static final String BLOG_POST_LINK = Quote.TABLE_NAME + "." + QuoteTable.BLOG_POST_LINK;

}

}

Quote 层基本上一对一地映射到数据库的 QuoteTable 和 QuoteFTS 层表示 FTS 表和 Quote 表之间的连接。(相应 fts 片段结果的片段列)这里我使用与数据库列名相同的列名,以便用户的投影和选择适合数据库。(包括表名,以便连接正常工作)

内容提供者的用户现在可以对提供的这两个虚拟数据库层进行各种查询,例如

Uri uri = QuoteContentProvider.FTS_URI;

switch (order) {
    case 1: {
        sortOrder = QuoteFTS.TITLE + " COLLATE NOCASE";
        break;
    }
    case 2: {
        sortOrder = QuoteFTS.AUTHOR + ", " + QuoteFTS.TITLE
                + " COLLATE NOCASE";
        break;
    }
    case 3: {
        sortOrder = QuoteFTS.QUOTE_LENGTH;
        break;
    }
}


String[] projection = new String[] { QuoteFTS._ID,
            QuoteFTS.TITLE, QuoteFTS.AUTHOR, QuoteFTS.SNIPPET}; 

String selection = titleOnly ? QuoteFTS.TITLE + " MATCH ? " : QuoteFTS.TABLE_NAME + " MATCH ? ";
String[] selectionArgs = {appendWildcard(query)};

Loader<Cursor> loader = CursorLoader(this, uri, projection,selection, selectionArgs, sortOrder);

仍然需要正确了解如何使用 MATCH 语法等才能使其正常工作。这一点让我感到有点不舒服,我非常感谢对此的反馈。

谢谢哥们

马丁

于 2012-09-11T12:40:19.737 回答