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に1対1でマッピングし、QuoteFTSレイヤーはFTSテーブルとQuoteテーブル間の結合を表します。(それぞれのftsスニペット結果のスニペット列)ここでは、データベースの列名と同じ列名を使用して、ユーザーの予測と選択がデータベースに適合するようにします。(結合がうまく機能するようにテーブル名を含む)

コンテンツプロバイダーのユーザーは、たとえば、提供されているこの2つの仮想データベースレイヤーに対してあらゆる種類のクエリを実行できるようになりました。

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 に答える