Java 我的房间数据库应该从版本0开始吗?
我意识到我的数据库迁移策略是不正确的,我已经重写了它。目前看起来是这样的:Java 我的房间数据库应该从版本0开始吗?,java,android,sqlite,android-room,Java,Android,Sqlite,Android Room,我意识到我的数据库迁移策略是不正确的,我已经重写了它。目前看起来是这样的: @Database(entities = {SaveData.class, Achievement.class}, version = 2, exportSchema = false) @TypeConverters(MapConverters.class) public abstract class AppDatabase extends RoomDatabase { public abstract Save
@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;
}
}
使用如下所示的帮助器类:
@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;
}
}
在getDatabaseLocked
方法中,我可以看到,如果从版本0开始,它将不会运行任何迁移,而是将版本设置为您要迁移到的任何版本
这种行为对我来说毫无意义,所以我认为我遗漏了什么。我尝试了一种简单的解决方法,就是强制迁移到1(通过创建一个不同的RoomDatabase
类),然后运行上面的方法。我还尝试手动将数据库版本设置为1,但这似乎也不是正确的解决方案
如果您需要更多上下文代码,请告诉我。我不确定您的问题是否解决了。很抱歉,如果我的回答在下面-事实并非如此
- Room是一个使用大量注释的框架,在构建过程中会生成大量自动生成的代码。它的一部分是对SQLite的查询,应该在应用程序启动时运行,并且找不到任何现有数据库。这些查询是根据实体的结构、索引、外键等形成的李>
- 假设您的数据库版本为1,在构建过程中生成了一些代码(代码#1),其中包含诸如“若不存在则创建表…”之类的查询
- 之后,您对表的结构做了一些更改,将版本更改为2。在构建过程中,生成了另一个代码(代码#2),其中包含一些不同的查询(包括您对表所做的更改)
- 您已经在设备应用程序上安装了版本1,调用了代码#1-创建了表(如果您不使用从资产中预填充数据库,则创建为空)。您开始用数据填充表格,然后-更新到版本2。此时,调用了MIGRATION_1_2块中的代码,以保存数据,并通过“特殊”查询更改表的结构
- 但如果您从设备上卸载了应用程序,然后安装了版本为2的应用程序,您的代码#2将被调用以创建版本2的实际表,不需要迁移,是吗?所以在本例中为“0”版本—之前安装的数据库版本,因为没有安装数据库—它是0李>
我不清楚您希望进行哪种迁移(在迁移过程中,有一些块带有insert-some值)。如果这个迁移中唯一的变化是——在一些表中插入一些预定义的值——那么也许你应该?啊,那么我想我误解了迁移对room的使用。我希望使用它们来填充数据库表。我没有意识到我应该只将它们用于结构数据库更改(列/表等)