本文地址:https://blog.csdn.net/qq_40785165/article/details/114706213,转载需附上此地址
大家好,我是小黑,一个还没秃头的程序员~~~
业精于勤,荒于嬉;行成于思,毁于随。
上一回我们讲了Jetpack组件Room配合AsyncTask、LiveData、ViewModel等的使用,这一次介绍的是如何管理Room数据库的版本更新与迁移,源码地址:https://gitee.com/fjjxxy/room-java-demo.git
首先介绍几种报错的情况
(一)直接添加Entity的列名,报错如下,表示你修改了数据库的结构却忘了更新数据库的版本号
(二)直接修改版本号,报错如下,提示你有个必要的版本1到版本2的迁移要做
(一)破坏式的迁移fallbackToDestructiveMigration,将数据清空,重新创建现有结构的数据库,这种方式是不建议的,除非你不在乎数据,毕竟数据是那么的重要,代码如下:
mDatabaseHelper = Room.databaseBuilder(context.getApplicationContext(), DatabaseHelper.class, "user")
.fallbackToDestructiveMigration()//迁移策略
.build();
(二)定义一个迁移策略,使用数据库语句对表结构进行修改,并将迁移策略传给addMigration(),这时我们在表中新增一个字段,如下列代码所示
mDatabaseHelper = Room.databaseBuilder(context.getApplicationContext(), DatabaseHelper.class, "user")
// .fallbackToDestructiveMigration()
.addMigrations(new Migration(2, 3) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
database.execSQL("ALTER TABLE user ADD COLUMN sex char(11) ");
}
})
.build();
(三)因为sqlit里面没有删除表的列的操作,所以这里如果我们想要删掉不想要的字段,可以使用以下四个步骤进行间接删除
代码如下,这里面需要细心,修改后的新的表的字段要和entity中规定的一样,包括字段类型,是否为空等,否则会报Migration didn't properly handle XXX的错误
mDatabaseHelper = Room.databaseBuilder(context.getApplicationContext(), DatabaseHelper.class, "user")
.addMigrations(migration3_4)
.build();
...
static final Migration migration3_4 = new Migration(3, 4) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
//先创建一个临时表
database.execSQL("CREATE TABLE user_temp(uid INTEGER PRIMARY KEY AUTOINCREMENT," +
"last_name TEXT,age INTEGER NOT NULL,sex TEXT )");
//将旧的表中的数据迁移过来
database.execSQL("INSERT INTO user_temp (uid,last_name,age,sex) SELECT uid,last_name,age,sex FROM user ");
//将旧的表删除
database.execSQL("DROP TABLE user");
//将临时表改名
database.execSQL("ALTER TABLE user_temp RENAME to user");
}
};
到此为止,Room数据库在保留数据的情况下进行版本更新以及迁移的功能也就介绍完毕了,感兴趣的小伙伴可以自己试试,最后,希望喜欢我文章的朋友们可以帮忙点赞、收藏、评论,也可以关注一下,如果有问题可以在评论区提出,谢谢大家的支持与阅读!