SQLite 使用内容提供程序检索外键值

SQLite retrieve foreign key values with content provider

我的 Android 应用程序中有一个包含 "label" 和 "idea" table 的 sqlite 数据库。在 idea table 上创建了一个外键作为 idea_label,其 int 值连接到其 _id 上的 label_table。

我使用 Loader 将我的 Cursor 加载到 mainActivity 上,从提供程序加载我的想法 table。很明显,它加载 idea_label int(但我寻求的是从 label_table 加载 label_body 中设置的值)。

我在 mainActivity 上的加载程序 class

@Override
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
    String[] projection = {
            DatabaseContract.IdeaEntry._ID,
            DatabaseContract.IdeaEntry.COLUMN_IDEA_NAME,
            DatabaseContract.IdeaEntry.COLUMN_IDEA_DESCRIPTION,
            DatabaseContract.IdeaEntry.COLUMN_IDEA_DATE,
            DatabaseContract.IdeaEntry.COLUMN_IDEA_LABEL,
            DatabaseContract.IdeaEntry.COLUMN_IDEA_ICON,
            DatabaseContract.IdeaEntry.COLUMN_IDEA_IS_ACTIVE,
            DatabaseContract.IdeaEntry.COLUMN_IDEA_IS_FAVORITE,
            DatabaseContract.IdeaEntry.COLUMN_IDEA_IS_DONE,
            DatabaseContract.IdeaEntry.COLUMN_IDEA_IS_ARCHIVED,
            DatabaseContract.IdeaEntry.COLUMN_IDEA_ORDER,
    };


    return new CursorLoader(this,
            DatabaseContract.IdeaEntry.CONTENT_URI_IDEA,
            projection,
            null,   // selection
            null,   // selectionArgs
            DatabaseContract.IdeaEntry.COLUMN_IDEA_ORDER   // order
    );
}

在我的提供商上调用此部分 class

@Nullable
@Override
public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
    SQLiteDatabase database = mDatabaseHelper.getReadableDatabase();
    Cursor cursor;

    int match = sUriMatcher.match(uri);
    switch (match){
        case IDEAS:
            cursor = database.query(DatabaseContract.IdeaEntry.IDEA_TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder);

有办法吗?触发另一个装载机?或者在这种情况下我的实现是错误的?任何方式或帮助指导我正确的方向,将不胜感激。

使用 SQLiteQueryBuilder 可以在 setTables 方法中加入 tables,然后只需在投影中指定标签 table 的 label_body 列。

        String[] projection = {
        DatabaseContract.IdeaEntry._ID,
        ....          
        DatabaseContract.LabelEntry.COLUMN_LABEL_BODY,
        };

        ...

        SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
        builder.setTables("IDEA JOIN LABEL ON IDEA.IDEA_LABEL = LABEL._ID");
        builder.query(database, projection, selection, selectionArgs, null, null, sortOrder);

感谢@gar_r 的帮助和指导,我对 DatabaseContract 常量做了这样的操作:

@Override
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
    String[] projection = {
            DatabaseContract.IdeaEntry.IDEA_TABLE_NAME + "." + DatabaseContract.IdeaEntry._ID,
            DatabaseContract.IdeaEntry.COLUMN_IDEA_NAME,
            DatabaseContract.IdeaEntry.COLUMN_IDEA_DESCRIPTION,
            DatabaseContract.IdeaEntry.COLUMN_IDEA_DATE,
            DatabaseContract.IdeaEntry.COLUMN_IDEA_LABEL,
            DatabaseContract.IdeaEntry.COLUMN_IDEA_ICON,
            DatabaseContract.IdeaEntry.COLUMN_IDEA_IS_ACTIVE,
            DatabaseContract.IdeaEntry.COLUMN_IDEA_IS_FAVORITE,
            DatabaseContract.IdeaEntry.COLUMN_IDEA_IS_DONE,
            DatabaseContract.IdeaEntry.COLUMN_IDEA_IS_ARCHIVED,
            DatabaseContract.IdeaEntry.COLUMN_IDEA_ORDER,
            DatabaseContract.LabelEntry.COLUMN_LABEL_BODY,
    };

    return new CursorLoader(this,
            DatabaseContract.IdeaEntry.CONTENT_URI_IDEA,
            projection,
            null,   // selection
            null,   // selectionArgs
            DatabaseContract.IdeaEntry.COLUMN_IDEA_ORDER   // order
    );
}

在我的提供商上调用此部分 class

@Nullable
@Override
public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
    SQLiteDatabase database = mDatabaseHelper.getReadableDatabase();
    Cursor cursor;

    int match = sUriMatcher.match(uri);
    switch (match){
        case IDEAS:
            SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
            builder.setTables(DatabaseContract.IdeaEntry.IDEA_TABLE_NAME + " JOIN " + DatabaseContract.LabelEntry.LABEL_TABLE_NAME
                    + " ON " + DatabaseContract.IdeaEntry.COLUMN_IDEA_LABEL + " = " + DatabaseContract.LabelEntry.LABEL_TABLE_NAME + "." + DatabaseContract.LabelEntry._ID);
            cursor = builder.query(database, projection, selection, selectionArgs, null, null, sortOrder);
            break;