Android数据库版本控制

时间:2011-08-29 08:02:03

标签: android sqlite versioning upgrade

我希望每次更新应用程序时都清除我的应用程序的sqlite数据库。 为此,我在SQLiteDatabase的“onUpgrade”函数中对所有表进行了drop table查询。

我遇到了两个问题: - 在我的应用程序的第一次启动时,我没有做任何特别的事情。 - 在第二次发布时,我添加了一个“setVersion(2)”行。它调用onUpgrade方法,但日志很奇怪:

public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
    Log.d("GDB", "onUpgrade "+oldVersion+" -> "+newVersion);
}
----------------------------------------------------------
DEBUG/GDB(5928): onUpgrade 2 -> 1

所以当我创建一个setVersion()时,这两个版本似乎被切换了.....

我的第二个问题是我第三次启动我的应用程序,而不更改代码(因此setVersion(2)已经在这里),再次调用onUpgrade方法!我是否遗漏了一些确定将版本设置为2的内容?

1 个答案:

答案 0 :(得分:3)

我认为您不应该使用setVersion方法直接在代码中设置数据库的版本。相反,您应该将架构版本传递到SQLiteOpenHelper的构造函数中(或者至少是扩展它的类)。然后,您的onUpgrade方法应包含条件语句,以根据用户从哪个版本升级来决定运行什么。这些条件应形成级联,以便来自低版本的顺序应用顺序所需的所有数据库更新,以使用户达到当前级别。 因此,当您想要更改架构时,可以向onUpgrade添加新条件,并向传递给构造函数的架构版本添加新条件。

这就是OpenHelper中的构造函数:

public TiftHelper(Context context) {
    super(context, DATABASE_NAME, null, SCHEMA_VERSION);
}

然后onUpgrade看起来像这样:

@Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        Log.d(TAG, "on upgrade called. Old version:" + oldVersion
                + ". New version:" + newVersion);

        if (oldVersion == 19) {
            db.execSQL("create table challenges_temp as select * from challenges;");
            db.execSQL("drop table challenges;");
            db.execSQL(create_challenges);
            db.execSQL("insert into challenges (_id, name, is_predef, status) select _id, name, is_predef, 'IN_PROGRESS' from challenges_temp");
            db.execSQL("drop table challenges_temp;");
        }
        if (oldVersion <= 20) {
            // adding the status column to the challenges table
            db.execSQL("create table challenges_temp as select * from challenges;");
            db.execSQL("drop table challenges;");
            db.execSQL(create_challenges);
            db.execSQL("insert into challenges (_id, name, is_predef, status) select _id, name, is_predef, 'IN_PROGRESS' from challenges_temp");
            db.execSQL("drop table challenges_temp;");
        }

这对我来说很好。