android内容提供商-隐藏内部复杂性但允许复杂查询的设计模式



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

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

我担心这是要走的路,但在实现它之前,我想听听周围安卓专业人士的一些建议。

非常感谢

martin

我现在的处境是这样的,至少我想快速分享一些解决方案,以获得鼓舞人心的专家反馈,并可能为周围的其他新手提供一些提示。现在看来,我一开始的基本错误是没有引入内容提供商向用户提供的类似"虚拟"数据库的层。一旦完成了这项工作,后面的复杂性就会隐藏起来,可以使用正常的查询语法。

因此,我所做的是在内容提供商合同类中拥有一个"虚拟"数据库层

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 snippet结果的snippet列)在这里,我使用与数据库列名相同的列名,以便用户的投影和选择适合数据库。(包括表名,以便联接工作良好)

内容提供商的用户现在可以在提供的这两个虚拟数据库层上进行所有类型的查询,例如

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语法等有适当的了解才能使其发挥作用。这一点让我感到有点不舒服,我非常感谢对此的反馈。

感谢伙伴

martin

最新更新