Room升级(三)

数据库升级

第一篇:Room的基本使用

第二篇:Room与LiveData、ViewModel结合使用

Migration

随着业务的变化,数据库可能也需要做一些调整,比如增加一个新字段,在Room中如何实现?Android为我们提供了一个Migration类对Room进行升级。

Migration有两个参数,startVersionendVersion,一个表示当前版本,一个表示将要升级到的版本。

使用方法

  1. 创建Migration
    private static final Migration MIGRATION_1_2 = new Migration(1, 2) {
        @Override
        public void migrate(@NonNull SupportSQLiteDatabase database) {
            //在这里做升级操作,比如增加或者减少表中的字段
            database.execSQL("ALTER TABLE emperor_table ADD COLUMN gender TEXT");
        }
    };
  1. 添加到构建数据库的实例中

     .addMigrations(MIGRATION_1_2)//可以添加多个参数,以便从1->2,2->3,1->3
    
  2. 最新版本号指定

    @Database(entities = {Emperor.class}, version = 2)
    

异常处理

为了防止升级过程中失败导致应用程序崩溃的情况,可以在创建数据库时加入fallbackToDestructiveMigration()方法。该方法能在数据库升级异常时,重建数据库而不崩溃,但是表中的数据会丢失。

Schemas文件查看版本升级情况

  • 如何查看Room升级情况

    • 在没有Room组件之前,若想要验证数据库的修改是否符合预期,我们需要找到这个数据库文件,接着使用第三方工具查看,对其进行查看和验证;
    • 如果我们想查看数据库历次版本升级情况,只能通过版本控制工具,根据代码修改情况进行推测。
  • Room如何解决这个问题

    • Room提供了一项功能,在每次数据库升级过程中,都会导出一个Schema文件,这是一个json格式的文件,包含数据库所有信息;

    • Schema默认是导出的,只需要在build.gradle中指定导出位置即可,若不想导出在进行如下设置即可

      @Database(entities = {Emperor.class}, version = 2, exportSchema = true)
      

销毁与重建策略

Sqlite中修改表结构比较麻烦,面对此类需求最好的方式是通过Migration采用销毁和重建策略

  • 创建一张符合表结构要求的临时表,
  • 将数据从旧表复制到临时表,
  • 删除旧表,
  • 临时表重命名回原来的表名

代码示例

    private static final Migration MIGRATION_2_3 = new Migration(2, 3) {
        @Override
        public void migrate(@NonNull SupportSQLiteDatabase database) {
            //创建临时表
            database.execSQL("CREATE TABLE tem_emperor (" + "id INTEGER PRIMARY KEY NOT NULL," +
                    "emperor_name TEXT," +
                    "age INTEGER," +
                    "gender TEXT)");
            //将数据导入临时表
            database.execSQL("INSERT INTO tem_emperor (id,emperor_name,age,gender) SELECT id,emperor_name,age,gender FROM emperor_table");
            //删除原表
            database.execSQL("DROP TABLE emperor_table");
            //临时表改成原表的名字
            database.execSQL("ALTER TABLE tem_emperor RENAME TO emperor_table");
        }
    };

全部代码请点击

你可能感兴趣的:(Jetpack,room,jetpack,android,数据库,移动开发)