拥有带有SQLite和多个表的ContentProvider

Nei*_*ard 11 android android-contentprovider

我正在阅读本教程,介绍如何使用我自己的ContentProvide来使用SQLite.在ContentProvider.query中有一些让我感到困惑的事情.它似乎非常硬编码只有一个表(教程中的待办事项表),但也许我只是没有得到它?现在如果我想查询另一个表,让我们说nodo,我将如何更改ContentProvider?

我应该在queryBuilder.setTables(String inTables)中以某种方式附加表名吗?

如果每个表都有一个CONTENT_TYPE和CONTENT_ITEM_TYPE怎么办?

关于TODO和TODO_ID varibles以及查询方法中的开关?

似乎我需要有很多if/switch条件来支持具有相同ContentProvider的多个表,这是要走的路还是我在错误的路径上?

谢谢
Søren

zap*_*apl 27

现在如果我想查询另一个表,让我们说nodo,我将如何更改ContentProvider?

查询新表意味着您需要添加新表Uri,因为Uri选择数据源,类似于使用不同的表.

您将基本上添加已存在的其他表的待办事项的所有硬编码值.例如:

// ------- usually the same for all
private static final String AUTHORITY = "de.vogella.android.todos.contentprovider";

// ------- define some Uris
private static final String PATH_TODOS = "todos";
private static final String PATH_REMINDERS = "reminders";

public static final Uri CONTENT_URI_TODOS = Uri.parse("content://" + AUTHORITY
    + "/" + PATH_TODOS);
public static final Uri CONTENT_URI_REMINDERS = Uri.parse("content://" + AUTHORITY
        + "/" + PATH_REMINDERS);

// ------- maybe also define CONTENT_TYPE for each

// ------- setup UriMatcher
private static final int TODOS = 10;
private static final int TODO_ID = 20;
private static final int REMINDERS = 30;
private static final int REMINDERS_ID = 40;
private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);
static {
  sURIMatcher.addURI(AUTHORITY, PATH_TODOS, TODOS);
  sURIMatcher.addURI(AUTHORITY, PATH_TODOS + "/#", TODO_ID);
  sURIMatcher.addURI(AUTHORITY, PATH_REMINDERS, REMINDERS);
  sURIMatcher.addURI(AUTHORITY, PATH_REMINDERS + "/#", REMINDERS_ID);
}

//@Override
public Cursor query(Uri uri, String[] projection, String selection,
        String[] selectionArgs, String sortOrder) {

    // Using SQLiteQueryBuilder instead of query() method
    SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();

    int uriType = sURIMatcher.match(uri);
    switch (uriType) {

        case TODO_ID:
            // Adding the ID to the original query
            queryBuilder.appendWhere(TodoTable.COLUMN_ID + "="
                    + uri.getLastPathSegment());
            //$FALL-THROUGH$
        case TODOS:
            queryBuilder.setTables(TodoTable.TABLE_TODO);
            break;

        case REMINDERS_ID:
            // Adding the ID to the original query
            queryBuilder.appendWhere(ReminderTable.COLUMN_ID + "="
                    + uri.getLastPathSegment());
            //$FALL-THROUGH$
        case REMINDERS:
            queryBuilder.setTables(ReminderTable.TABLE_REMINDER);
            break;

        default:
            throw new IllegalArgumentException("Unknown URI: " + uri);
  }
Run Code Online (Sandbox Code Playgroud)

我应该在queryBuilder.setTables(String inTables)中以某种方式附加表名吗?

是的,如果Uri从不同的表中读取不同的s ,则根据Uri匹配设置表.

如果每个表都有一个CONTENT_TYPE和CONTENT_ITEM_TYPE怎么办?

取决于实际的内容类型.如果它们不同并且您需要类型是.但你根本不需要它们.该示例定义了它们,但甚至没有使用它们.它需要返回类型getType,请参阅文档.

关于TODO和TODO_ID varibles以及查询方法中的开关?

这些是定义的常量,这里UriMatcher很好地解释.它基本上是字符串匹配的简化.一个大的ContentProvider可以拥有100个不同的Uris并选择正确的桌子query如果你必须一直写的话会很痛苦if (uri.getPath().equals("todos") { /* code */ } else if (uri...