【问题标题】:Own ContentProvider with SQLite and multiple tables拥有 SQLite 和多个表的 ContentProvider
【发布时间】:2012-11-26 20:10:46
【问题描述】:

我正在阅读 this tutorial 以实现我自己的 ContentProvide 以使用 SQLite。在 ContentProvider.query 中,有几件事让我感到困惑。似乎对一张表(教程中的 todo 表)进行了硬编码,但也许我只是没有得到它?现在,如果我想查询另一个表,比如说 nodo,我将如何更改 ContentProvider?

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

CONTENT_TYPE 和 CONTENT_ITEM_TYPE 呢,每个表应该都有一个吗?

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

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

谢谢
索伦

【问题讨论】:

  • 1. setTables...这取决于您的需要,如果您需要加入,您应该但仍然点 2... 2. 内容 mime... 是 3. 再次为每个表。 4. 路径错误...不,我认为这是一条好路径...您可以尝试搜索/编写某种生成器 fx selvin.pl/autocontent.zip

标签: android android-contentprovider


【解决方案1】:

现在如果我想查询另一个表,比如说 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);
  }

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

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

那 CONTENT_TYPE 和 CONTENT_ITEM_TYPE 呢,每张表应该都有一个吗?

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

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

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

【讨论】:

  • 嗨,在这种情况下,您将如何实现删除方法?你能帮忙吗?
【解决方案2】:

这里是solution 给您的问题,使用 UriMatcher,您可以在内容提供程序中实现多个表。

【讨论】:

    【解决方案3】:

    内容类型和内容项可以如下,并且可以为每个表包装在单独的类中

    public static final String GENERAL_CONTENT_TYPE = "vnd.android.cursor.dir/vnd.myfirstapp.db.member" ; public static final String SPECIFIC_CONTENT_TYPE = "vnd.android.cursor.item/vnd.myfirstapp.db.member" ;

    `vnd.android.cursor.dir/vnd.yourownanything.anything.tablename'

    这定义了一般内容类型 `vnd.android.cursor.item/vnd.anthingasabove.table' 这也定义了特定的,并且对于任何应用程序都是恒定的,那些字符串(单词)vnd.android.cursor.dir 和 .item 必须是这样的并且在 /vnd 之后。应该是这样的

    在扩展 contentprovider 的类中,您只需使用相同的 UriMatcher 实例来映射表

    【讨论】:

      猜你喜欢
      • 2012-04-10
      • 1970-01-01
      • 2019-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-16
      • 1970-01-01
      相关资源
      最近更新 更多