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;
我的 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;