android - SQLiteOpenHelper onUpgrade() 混淆Android

标签 android database sqlite

我正在使用数据库开发我的第一个应用程序,但我在理解 onUpgrade 函数时遇到了一些问题。我的数据库有一个表,其中包含一个项目和一个收藏列,以便用户可以收藏一个项目。我看到的大多数实现只是删除表并重建它,但我不想这样做。我希望能够向表中添加更多项目。

当应用程序通过 android 市场升级时,数据库是否知道它的版本号?那么我可以增加代码中的版本号,然后将其导出到市场,当用户第一次启动升级版本时,会调用 onUpgrade 吗?

如果是这种情况,我的 onUpgrade 会简单地从文件中提取并添加数据库项。这是一种标准的做事方式,还是在 Android 中有更好的处理方式。我尽量保持标准。

谢谢

最佳答案

好的,在遇到更大的问题之前,您应该知道 SQLite 仅限于 ALTER TABLE 命令,它允许 addrename只有没有删除/删除是通过重新创建表来完成的。

您应该随时准备好新的表创建查询,并将其用于升级和传输任何现有数据。注意:onUpgrade 方法为您的 sqlite 助手对象运行一个方法,您需要处理其中的所有表。

那么在Upgrade上有什么推荐:

  • 开始交易
  • 使用 if not exists 运行表创建(我们正在升级,所以该表可能还不存在,它会更改失败并删除)
  • 列出现有列List<String> columns = DBUtils.GetColumns(db, TableName);
  • 备份表 (ALTER table " + TableName + " RENAME TO 'temp_" + TableName)
  • 创建新表(最新的表创建架构)
  • 获取与新列的交集,这次的列取自升级后的表 (columns.retainAll(DBUtils.GetColumns(db, TableName));)
  • 恢复数据 (String cols = StringUtils.join(columns, ","); db.execSQL(String.format( "INSERT INTO %s (%s) SELECT %s from temp_%s", TableName, cols, cols, TableName)); )
  • 删除备份表 (DROP table 'temp_" + TableName)
  • setTransactionSuccessful

(这不处理表降级,如果重命名列,则不会传输现有数据,因为列名不匹配)。

.

public static List<String> GetColumns(SQLiteDatabase db, String tableName) {
    List<String> ar = null;
    Cursor c = null;
    try {
        c = db.rawQuery("select * from " + tableName + " limit 1", null);
        if (c != null) {
            ar = new ArrayList<String>(Arrays.asList(c.getColumnNames()));
        }
    } catch (Exception e) {
        Log.v(tableName, e.getMessage(), e);
        e.printStackTrace();
    } finally {
        if (c != null)
            c.close();
    }
    return ar;
}

public static String join(List<String> list, String delim) {
    StringBuilder buf = new StringBuilder();
    int num = list.size();
    for (int i = 0; i < num; i++) {
        if (i != 0)
            buf.append(delim);
        buf.append((String) list.get(i));
    }
    return buf.toString();
}

关于android - SQLiteOpenHelper onUpgrade() 混淆Android,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3505900/

相关文章:

android - 如何将进度对话框附加到 onClick 事件

sql - 将数据库模式导出到 SQL 文件

c# - 一个易于开发人员使用和部署的数据库?

java - 从数据库填充 ListView 项时获取其 ID

android - 如何使用 onSaveInstanceState

java - 无法使用 EclipsePortable 为 Android 指定 targetSDKVersion

android - Firebase 匿名身份验证 (Android) : Lifetime?

ruby-on-rails - 希望将YouTube视频数据存储到我的Rails数据库中

c# - SQLite 不支持此迁移操作 ('DropForeignKeyOperation' )

mysql - 原生 XML 数据库与 SQLite/MySQL