数据迁移是如何工作的?
在sqlite中,所谓迁移是修改现有的数据库的设计结构,以适应新的数据结构。
在sqlite中,我们很有限的去比较sql,从而去修改表和列。
现在有两种方式去修改:
- 重命名表
- 添加新的列
DBFlow 可以做到的:
- 修改数据库的结构
- 向数据库中提前插入数据
- 为指定的表添加索引
迁移的一些类
我们推荐将 Migration的类放在注解@Table的类中。因为显而易见嘛!
小例子:
Migration可设置优先级,高优先级的将先被执行。
Migration有3个方法:
- onPreMigrate() 首先被调用,在这儿设置和构造
- migrate() 具体的迁移在这儿执行
- onPostMigrate() 执行一些清理工作,或者执行完成的通知。
迁移文件
DBFlow也支持.sql文件,规则如下:
- 放置他们到 assets/migrations/{DATABASE_NAME}/{versionNumber}.sql ,例如:assets/migrations/AppDatabase/2.sql
- 文件内可包括任意数量的sql语句,注意:每个语句为单独一行,多行则在尾部加上;
- --为注释
防止迭代访问数据库
在迁移的时候,数据库是打开的。我们不可用迭代的访问数据库对象。
记住:DBFlow传递了DatabaseWrapper 给你:
- 增删改查:Select Insert Update Delete
- 所有的BaseModel的子类
提供的迁移类
DBFlow 提供了几个迁移类帮助你简单的迁移
- AlterTableMigration
- IndexMigration/IndexPropertyMigration
- UpdateTableMigration
1. AlterTableMigration
修改表的结构
支持的修改:
- 重命名 表的名字
- 添加列
重命名 表的名字
在迁移之前,你应该先重命名你的model类@Table(name = "{newName}")
添加新的列
我们只支持SQLiteType去添加或移除新的列。
@Migration(version = 2, database = AppDatabase.class)
public class Migration2 extends AlterTableMigration<AModel> {
public Migration2(Class<AModel> table) {
super(table);
}
@Override
public void onPreMigrate() {
addColumn(SQLiteType.TEXT, "myColumn");
addColumn(SQLiteType.REAL, "anotherColumn");
}
}
2.Index Migrations
IndexMigration:
@Migration(version = 2, priority = 0, database = MigrationDatabase.class)
public static class IndexMigration2 extends IndexMigration<MigrationModel> {
public IndexMigration2(@NonNull Class<MigrationModel> onTable) {
super(onTable);
}
@NonNull
@Override
public String getName() {
return "TestIndex";
}
}
IndexPropertyMigration:
@Migration(version = 2, priority = 1, database = MigrationDatabase.class)
public static class IndexPropertyMigration2 extends IndexPropertyMigration {
@NonNull
@Override
public IndexProperty getIndexProperty() {
return IndexModel_Table.index_customIndex;
}
}
3. Update Table Migration
提供简单的方式去更新数据
@Migration(version = 2, priority = 2, database = MigrationDatabase.class)
public static class UpdateMigration2 extends UpdateTableMigration<MigrationModel> {
/**
* Creates an update migration.
*
* @param table The table to update
*/
public UpdateMigration2(Class<MigrationModel> table) {
super(table);
set(MigrationModel_Table.name.eq("New Name"));
}
}