Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/199.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我的房间数据库应该从版本0开始吗?_Java_Android_Sqlite_Android Room - Fatal编程技术网

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的使用。我希望使用它们来填充数据库表。我没有意识到我应该只将它们用于结构数据库更改(列/表等)