Android—Room 数据库迁移(Migration)

Android-Room数据库(介绍)

Android-Room数据库-多表查询(Relationships)

Android—Room自定义类型(TypeConverter)

Android — Room 数据库跳跃式升级(Migration)

前言

如果大家看到了这里,那大家就可以正常使用Room数据库了。因为业务的变更,我们时常会添加数据库字段。这时候咱们就需要去升级数据库了。

如果咱们删除了一个字段,运行程序后,就会出现下面这个问题。

java.lang.IllegalStateException: Room cannot verify the data integrity. Looks like you've changed schema but forgot to update the version number. You can simply fix this by increasing the version number.
大致的意思是:你修改了数据库,但是没有升级数据库的版本

这时候咱们根据错误提示增加版本号,但没有提供migration,APP一样会crash。

java.lang.IllegalStateException: A migration from 1 to 2 was required but not found. Please provide the necessary Migration path via RoomDatabase.Builder.addMigration(Migration ...) or allow for destructive migrations via one of the RoomDatabase.Builder.fallbackToDestructiveMigration* methods.
大致的意思是:让我们添加一个addMigration或者调用fallbackToDestructiveMigration完成迁移

接下来,咱们增加版本号并使用fallbackToDestructiveMigration(),虽然可以使用了,但是我们会发现,数据库的内容都被我们清空了。显然这种方式是不友好的,

Room.databaseBuilder(
context,
DepartmentDatabase.class,
DB_NAME).allowMainThreadQueries()
.fallbackToDestructiveMigration()
.build();

如果咱们不想清空数据库,就需要提供一个实现了的migration
比如咱们要在Department中添加phoneNum

public class Department {
    @PrimaryKey(autoGenerate = true)
    private int id;
    private String dept;
    @ColumnInfo(name = "emp_id")
    private int empId;
    @ColumnInfo(name = "phone_num")
    private String phoneNum;
}

1、把版本号自增

@Database(entities = {Department.class, Company.class}, version = 2, exportSchema = false)
@TypeConverters(DateConverter.class)
public abstract class DepartmentDatabase extends RoomDatabase {
   ...
}

2、添加一个version:1->2的migration

static final Migration MIGRATION_1_2 = new Migration(1, 2) {
    @Override
    public void migrate(SupportSQLiteDatabase database) {
        database.execSQL("ALTER TABLE department "
                + " ADD COLUMN phone_num TEXT");
    }
};

当添加的数据类型为 int 时,需要添加默认值 "ALTER TABLE department " + " ADD COLUMN phone_num INTEGER NOT NULL DEFAULT 0"

3、把migration 添加到 databaseBuilder

Room.databaseBuilder(
context,
DepartmentDatabase.class,
DB_NAME).allowMainThreadQueries()
.addMigrations(MIGRATION_1_2)
.build();

再次运行APP就会发现,数据库表更新了,并且旧数据也保留了。

到这里Room基本用法就结束啦。

推荐阅读更多精彩内容