我对与内容提供商实施复杂查询的最佳做法有疑问。正如我从android联系内容提供商那里看到的,建议使用选择, selectionArgs 等字段来发出特定请求。
我现在正在塑造我的第一个自己的内容提供商。它有一个非常复杂的野兽与所有连接,全文表等具有规范化表的数据库的构造。当然,我想隐藏内容提供者的用户的这种复杂性,但我还不知道如何实现这一点。如果用户使用选择, selectionArgs 等指定了他的请求,则内容提供商似乎必须解析这些请求并将其映射到底层结构。是否有一些用于此解析的工具,或者我最终会编写自己的选择字符串解析器等。
我担心这是要走的路,但在实施之前,我想听听Android专业人士的一些建议。
非常感谢
马丁
答案 0 :(得分: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语法等来使其正常工作。这一点让我觉得有点不舒服,我非常感谢对此的反馈。
谢谢好友
马丁