本文正在参加「金石计划」

前语

咱们前面一篇介绍了运用 floor 这个 ORM 结构处理 Flutter 本地的 SQLite 数据库。运用 ORM 结构最大的优点是简化了数据库保护的代码量,使得咱们能够专心于业务代码实现。在之前,咱们也讲到了不同 App 版别的 数据表结构变化后,如何运用 sqflite 来处理版别晋级。本篇,咱们看看运用 floor 如何处理数据库版别晋级。

floor 数据库版别晋级

floor 结构同样供给了数据库版别号,当时运用的版别号运用注解配置。

@Database(version: 1, entities: [Memo])

当数据表结构发生变化时,就需要改变版别号指定新的版别。同时需要做如下处理:

  • 更新实体类:比方增加或削减字段,改变字段类型等等;
  • 编写搬迁处理Migration类目标,Migration 类定义如下:
Migration(this.startVersion, this.endVersion, this.migrate)

其间第一个参数为起始版别号,第二个参数为要搬迁到的版别号,最后是一个搬迁处理函数,函数定义为:Future<void> Function(sqflite.Database database) migrate。咱们要做的数据表变化就在这个函数里处理。

  • 将编写好的Migration类目标增加到数据库初始化的 addMigrations 方法中,addMigrations方法接纳一个Migration目标数组,因此是支持多种搬迁的,比方从版别1搬迁到版别3的搬迁目标,从版别2搬迁到版别3的搬迁目标,从而满意多个版别同时搬迁。
final database = await $FloorAppDatabase
    .databaseBuilder('app_database.db')
    .addMigrations([migration1to3, migration2to3])
    .build();
  • 实体类改变后,需要用代码生成指令重新生成数据库操作的相关代码。

看起来非常简略,咱们来看实际的比如。

版别晋级实例

咱们给之前的备忘录增加一个分类(category)字段,能够设置备忘录的分类,分类咱们简略地固定为预设的几类。咱们按照上面的步骤一步步编写代码即可。

  • 改变版别:将数据库版别号改为2;
@Database(version: 2, entities: [Memo])
  • 在备忘录类增加分类字段,因为已有数据的分类字段是 null 的,因此需要设置这个字段可为空Nullable;设置为非空也能够,仅仅需要在搬迁时给旧版别已有数据相应字段设置非空初始值。
@entity
class Memo {
  @PrimaryKey(autoGenerate: true)
  final int? id;
  String title;
  String content;
  @ColumnInfo(name: 'created_time')
  DateTime createdTime;
  @ColumnInfo(name: 'modified_time')
  DateTime modifiedTime;
  String? category;
  List<String> tags;
  Memo({
    this.id,
    required this.title,
    required this.content,
    required this.createdTime,
    required this.modifiedTime,
    this.category = '',
    required this.tags,
  });
}
  • 编写数据库搬迁处理目标,并加入到版别搬迁中。
final migration1to2 = Migration(1, 2, (database) async {
  await database.execute('ALTER TABLE Memo ADD COLUMN category TEXT');
  // 可选,设置旧版别字段初始值
  await database.update('Memo',{'category': ''});
});
Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final database = await $FloorMemoDatabase
      .databaseBuilder('app_database.db')
      .addMigrations([migration1to2]).build();
  final dao = database.memoDao;
  getIt.registerSingleton<MemoDao>(dao, signalsReady: true);
  runApp(const MyApp());
}
  • 运转下面的指令生成代码。
flutter packages pub run build_runner build

当然,咱们也需要对 UI 相关的代码进行改变,改变后的 UI 界面如下图所示。

Flutter 使用 ORM 框架管理数据库版本迁移
完整代码现已提交到:本地存储相关代码。

总结

从代码量上来说,运用 floor 和直接运用 sqflite 处理版别搬迁差不多。相比直接运用 sqflite 做数据库版别搬迁,运用 floor 的优点是能够通过增加多个 Migration 目标支持多版别搬迁。

我是岛上码农,微信公众号同名。如有问题能够加自己微信沟通,微信号:island-coder

:觉得有收成请点个赞鼓舞一下!

:保藏文章,方便回看哦!

:谈论沟通,互相前进!

本文正在参加「金石计划」