【发布时间】:2020-05-27 18:26:07
【问题描述】:
我意识到我的数据库迁移策略不正确并重写了它。目前它看起来像这样:
@Database(entities = {SaveData.class, Achievement.class}, version = 2, exportSchema = false)
@TypeConverters(MapConverters.class)
public abstract class AppDatabase extends RoomDatabase {
public abstract SaveDataDAO saveDataDAO();
public abstract AchievementDAO achievementDAO();
}
使用如下所示的辅助类:
public class AppDatabaseHelper {
private static AppDatabase db;
private AppDatabaseHelper() {
// static utility
}
private static final Migration MIGRATION_1_2 =
new Migration(1, 2) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
Set<AchievementType> achievementTypes = EnumSet.allOf(AchievementType.class);
String values = achievementTypes.stream().map(AppDatabaseHelper::createRow).collect(Collectors.joining(", "));
String fullQuery = "INSERT OR IGNORE INTO Achievement(name, current, total) VALUES " + values;
database.execSQL(fullQuery);
}
};
private static String createRow(AchievementType achievementType) {
String name = achievementType.name();
int total = achievementType.getTotal();
return String.format("('%s',0,%s)", name, total);
}
public static AppDatabase getDatabase(Context context) {
if (db == null) {
db = Room.databaseBuilder(context.getApplicationContext(),
AppDatabase.class, "game")
.addMigrations(MIGRATION_1_2)
.build();
}
return db;
}
}
当我删除数据库并运行应用程序时,第一次访问数据库并没有按预期运行此迁移。相反,我可以看到SQLLiteOpenHelper.java 内部的数据库版本为0,正在尝试迁移到2。由于Android helper 类的这个特定部分:
db.beginTransaction();
try {
if (version == 0) {
onCreate(db);
} else {
if (version > mNewVersion) {
onDowngrade(db, version, mNewVersion);
} else {
onUpgrade(db, version, mNewVersion);
}
}
db.setVersion(mNewVersion);
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
在 getDatabaseLocked 方法中,我可以看到如果它从版本 0 开始,它不会运行任何迁移,而是将版本设置为您要迁移的任何版本。
这种行为对我来说没有任何意义,所以我认为我遗漏了一些东西。我尝试了一个 hacky 解决方法,即强制迁移到 1(通过创建不同的 RoomDatabase 类)然后运行上面的工作。我也尝试过手动将数据库版本设置为 1,但这似乎也不是正确的解决方案。
如果您需要更多上下文代码,请告诉我
【问题讨论】:
标签: java android sqlite android-room