具有 4 个数据库版本的 SQLite onUpgrade
SQLite onUpgrade with 4 database versions
当我们有 4 个数据库版本并且我们在每个版本中为用户 table 添加了一个新字段时,执行 SQLiteOpenHelper 的 onUpgrade 方法的正确方法是什么?
变体 A:// 每个案例后没有 "break",案例 2 和案例 3 是否保持 运行?
public void onUpgrade(SQLiteDatabase database, int version_old, int current_version) {
switch (version_old) {
case 1:
database.execSQL(addPostcodeFieldToUserTable);
case 2:
database.execSQL(addGenderFieldToUserTable);
case 3:
database.execSQL(addEmailSubscriptionFieldToUserTable);
break;
}
}
变体 B:
public void onUpgrade(SQLiteDatabase database, int version_old, int current_version) {
switch (version_old) {
case 1:
database.execSQL(addPostcodeFieldToUserTable);
break;
case 2:
database.execSQL(addPostcodeFieldToUserTable);
database.execSQL(addGenderFieldToUserTable);
break;
case 3:
database.execSQL(addPostcodeFieldToUserTable);
database.execSQL(addGenderFieldToUserTable);
database.execSQL(addEmailSubscriptionFieldToUserTable);
break;
}
但是,如果用户拥有第 1 版数据库,然后错过第 2 版并使用第 3 版升级应用程序,我们该怎么办?
变体 3:
public void onUpgrade(SQLiteDatabase database, int version_old, int current_version) {
if(version_old==1 && current_version==2) {
database.execSQL(addPostcodeFieldToUserTable);
} else if(version_old==2 && current_version==3) {
database.execSQL(addGenderFieldToUserTable);
} else if(version_old==3 && current_version==4) {
database.execSQL(addEmailSubscriptionFieldToUserTable);
} else if(version_old==1 && current_version==3) {
database.execSQL(addPostcodeFieldToUserTable);
database.execSQL(addGenderFieldToUserTable);
} else if(version_old==1 && current_version==4) {
database.execSQL(addPostcodeFieldToUserTable);
database.execSQL(addGenderFieldToUserTable);
database.execSQL(addEmailSubscriptionFieldToUserTable);
} else if(version_old==2 && current_version==4) {
database.execSQL(addGenderFieldToUserTable);
database.execSQL(addEmailSubscriptionFieldToUserTable);
}
}
你还可以做的是使 onUpgrade 成为一个递归调用,
public void onUpgrade(SQLiteDatabase database, int version_old, int current_version) {
switch (version_old) {
case 1:
database.execSQL(addPostcodeFieldToUserTable);
onUpgrade(database,version_old++,current_version);
break;
case 2:
database.execSQL(addPostcodeFieldToUserTable);
database.execSQL(addGenderFieldToUserTable);
onUpgrade(database,version_old++,current_version)
break;
default:
break;
}
你明白了,所以它会升级到最新版本并停止调用自己。
No "break" after each case, does it keep running for case 2 and 3?
是的。通常的做法是添加评论,例如
// fallthrough
表示遗漏break
是故意的。
But what do we do in the case when a user had version 1 of the DB, then missed version 2 and upgraded the app with version 3?
onUprade()
将使用 oldVersion
1 和 newVersion
3 调用。代码应将数据库更新到架构的版本 3。
使用哪个变体取决于哪个对您来说维护起来最舒服。我个人会选择变体 A 之类的东西,因为它的代码最少。
在没有 break
的情况下使用 switch
是违反直觉的。
一个常见的模式是使用一系列 if
代替:
if (version_old < 2) {
database.execSQL(addPostcodeFieldToUserTable);
}
if (version_old < 3) {
database.execSQL(addGenderFieldToUserTable);
}
if (version_old < 4) {
database.execSQL(addEmailSubscriptionFieldToUserTable);
}
当我们有 4 个数据库版本并且我们在每个版本中为用户 table 添加了一个新字段时,执行 SQLiteOpenHelper 的 onUpgrade 方法的正确方法是什么?
变体 A:// 每个案例后没有 "break",案例 2 和案例 3 是否保持 运行?
public void onUpgrade(SQLiteDatabase database, int version_old, int current_version) {
switch (version_old) {
case 1:
database.execSQL(addPostcodeFieldToUserTable);
case 2:
database.execSQL(addGenderFieldToUserTable);
case 3:
database.execSQL(addEmailSubscriptionFieldToUserTable);
break;
}
}
变体 B:
public void onUpgrade(SQLiteDatabase database, int version_old, int current_version) {
switch (version_old) {
case 1:
database.execSQL(addPostcodeFieldToUserTable);
break;
case 2:
database.execSQL(addPostcodeFieldToUserTable);
database.execSQL(addGenderFieldToUserTable);
break;
case 3:
database.execSQL(addPostcodeFieldToUserTable);
database.execSQL(addGenderFieldToUserTable);
database.execSQL(addEmailSubscriptionFieldToUserTable);
break;
}
但是,如果用户拥有第 1 版数据库,然后错过第 2 版并使用第 3 版升级应用程序,我们该怎么办?
变体 3:
public void onUpgrade(SQLiteDatabase database, int version_old, int current_version) {
if(version_old==1 && current_version==2) {
database.execSQL(addPostcodeFieldToUserTable);
} else if(version_old==2 && current_version==3) {
database.execSQL(addGenderFieldToUserTable);
} else if(version_old==3 && current_version==4) {
database.execSQL(addEmailSubscriptionFieldToUserTable);
} else if(version_old==1 && current_version==3) {
database.execSQL(addPostcodeFieldToUserTable);
database.execSQL(addGenderFieldToUserTable);
} else if(version_old==1 && current_version==4) {
database.execSQL(addPostcodeFieldToUserTable);
database.execSQL(addGenderFieldToUserTable);
database.execSQL(addEmailSubscriptionFieldToUserTable);
} else if(version_old==2 && current_version==4) {
database.execSQL(addGenderFieldToUserTable);
database.execSQL(addEmailSubscriptionFieldToUserTable);
}
}
你还可以做的是使 onUpgrade 成为一个递归调用,
public void onUpgrade(SQLiteDatabase database, int version_old, int current_version) {
switch (version_old) {
case 1:
database.execSQL(addPostcodeFieldToUserTable);
onUpgrade(database,version_old++,current_version);
break;
case 2:
database.execSQL(addPostcodeFieldToUserTable);
database.execSQL(addGenderFieldToUserTable);
onUpgrade(database,version_old++,current_version)
break;
default:
break;
}
你明白了,所以它会升级到最新版本并停止调用自己。
No "break" after each case, does it keep running for case 2 and 3?
是的。通常的做法是添加评论,例如
// fallthrough
表示遗漏break
是故意的。
But what do we do in the case when a user had version 1 of the DB, then missed version 2 and upgraded the app with version 3?
onUprade()
将使用 oldVersion
1 和 newVersion
3 调用。代码应将数据库更新到架构的版本 3。
使用哪个变体取决于哪个对您来说维护起来最舒服。我个人会选择变体 A 之类的东西,因为它的代码最少。
在没有 break
的情况下使用 switch
是违反直觉的。
一个常见的模式是使用一系列 if
代替:
if (version_old < 2) {
database.execSQL(addPostcodeFieldToUserTable);
}
if (version_old < 3) {
database.execSQL(addGenderFieldToUserTable);
}
if (version_old < 4) {
database.execSQL(addEmailSubscriptionFieldToUserTable);
}