Flutter数据库迁移插件migrant_db_sqlite的使用

发布于 1周前 作者 gougou168 来自 Flutter

Flutter数据库迁移插件migrant_db_sqlite的使用

SQLite gateway for migrant。

示例

import 'package:migrant/migrant.dart';
import 'package:migrant/testing.dart';
import 'package:migrant_db_sqlite/migrant_db_sqlite.dart';
import 'package:sqflite_common/sqlite_api.dart' show inMemoryDatabasePath;
import 'package:sqflite_common_ffi/sqflite_ffi.dart' show databaseFactoryFfi;

Future<void> main() async {
  // 这些是迁移脚本。我们使用一个简单的内存源,
  // 但你可以从其他来源读取它们:本地文件系统、网络等。
  // 更多选项在 https://pub.dev/packages/migrant
  final migrations = InMemory([
    Migration('0001', ['CREATE TABLE foo (id TEXT NOT NULL PRIMARY KEY);']), // 创建表foo
    Migration('0002', ['ALTER TABLE foo ADD COLUMN message TEXT;']), // 在表foo中添加message列
    // 尝试在这里添加更多内容并再次运行此示例。
  ]);

  // SQLite连接。我们使用一个本地文件。
  var connection = await databaseFactoryFfi.openDatabase(inMemoryDatabasePath);

  // 网关由该包提供。
  final gateway = SQLiteGateway(connection);

  // 应用迁移。
  await Database(gateway).upgrade(migrations);
  // 此时表"foo"已经准备好。
}

完整示例Demo

import 'package:migrant/migrant.dart';
import 'package:migrant/testing.dart';
import 'package:migrant_db_sqlite/migrant_db_sqlite.dart';
import 'package:sqflite_common/sqlite_api.dart' show inMemoryDatabasePath;
import 'package:sqflite_common_ffi/sqflite_ffi.dart' show databaseFactoryFfi;

Future<void> main() async {
  // 迁移脚本。使用内存源
  final migrations = InMemory([
    Migration('0001', ['CREATE TABLE foo (id TEXT NOT NULL PRIMARY KEY);']), // 创建表foo
    Migration('0002', ['ALTER TABLE foo ADD COLUMN message TEXT;']), // 在表foo中添加message列
    // 可以尝试在此处添加更多迁移步骤
  ]);

  // 打开SQLite数据库连接
  var connection = await databaseFactoryFfi.openDatabase(inMemoryDatabasePath);

  // 使用SQLite网关
  final gateway = SQLiteGateway(connection);

  // 应用迁移
  await Database(gateway).upgrade(migrations);

  // 此时表"foo"已经准备好
}

更多关于Flutter数据库迁移插件migrant_db_sqlite的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter数据库迁移插件migrant_db_sqlite的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何使用 migrant_db_sqlite 插件进行 Flutter 数据库迁移的示例代码。这个插件允许你管理 SQLite 数据库的版本并进行迁移。

首先,确保你已经在 pubspec.yaml 文件中添加了 migrant_db_sqlite 依赖:

dependencies:
  flutter:
    sdk: flutter
  migrant_db_sqlite: ^最新版本号  # 请替换为实际最新版本号

然后,运行 flutter pub get 来获取依赖。

接下来,创建一个数据库管理类,负责数据库的打开、版本管理和迁移。

import 'package:flutter/material.dart';
import 'package:migrant_db_sqlite/migrant_db_sqlite.dart';

class DatabaseManager {
  static DatabaseManager? _instance;
  late MigrantDB _db;

  DatabaseManager._();

  factory DatabaseManager() {
    if (_instance == null) {
      _instance = DatabaseManager._();
    }
    return _instance!;
  }

  Future<void> initDatabase() async {
    _db = MigrantDB(
      dbPath: 'example.db',
      version: 2, // 当前数据库版本
      onConfigure: (db) async {
        // 在这里创建初始表
        await db.execute('''
          CREATE TABLE IF NOT EXISTS user (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            name TEXT NOT NULL,
            email TEXT NOT NULL UNIQUE
          )
        ''');
      },
      onUpgrade: (db, oldVersion, newVersion) async {
        if (oldVersion < 2) {
          // 版本 1 到版本 2 的迁移:添加一个新的列
          await db.execute('ALTER TABLE user ADD COLUMN age INTEGER');
        }
      },
      onDowngrade: (db, oldVersion, newVersion) async {
        // 可选的降级逻辑
      },
    );

    await _db.open();
  }

  Future<void> insertUser(String name, String email, int? age) async {
    await _db.transaction((db) async {
      await db.insert(
        'user',
        {
          'name': name,
          'email': email,
          'age': age,
        },
        conflictAlgorithm: ConflictAlgorithm.replace,
      );
    });
  }

  Future<List<Map<String, dynamic>>> getUsers() async {
    return await _db.query('user');
  }

  Future<void> close() async {
    await _db.close();
  }
}

在你的应用中初始化并使用这个数据库管理类:

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter Database Migration Example'),
        ),
        body: FutureBuilder<void>(
          future: _initializeDatabase(),
          builder: (context, snapshot) {
            if (snapshot.connectionState == ConnectionState.done) {
              if (snapshot.hasError) {
                return Text('Failed to initialize database: ${snapshot.error!}');
              } else {
                return MyHomePage();
              }
            } else {
              return CircularProgressIndicator();
            }
          },
        ),
      ),
    );
  }

  Future<void> _initializeDatabase() async {
    final DatabaseManager dbManager = DatabaseManager();
    await dbManager.initDatabase();
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final DatabaseManager _dbManager = DatabaseManager();

  @override
  void initState() {
    super.initState();
    // 示例:插入用户数据
    _dbManager.insertUser('Alice', 'alice@example.com', 30);
    _dbManager.insertUser('Bob', 'bob@example.com', null);
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<List<Map<String, dynamic>>>(
      future: _dbManager.getUsers(),
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.done) {
          if (snapshot.hasError) {
            return Text('Failed to fetch users: ${snapshot.error!}');
          } else {
            final users = snapshot.data ?? [];
            return ListView.builder(
              itemCount: users.length,
              itemBuilder: (context, index) {
                final user = users[index];
                return ListTile(
                  title: Text('${user['name']} (${user['email']})'),
                  subtitle: user['age'] != null
                      ? Text('Age: ${user['age']}')
                      : Text('Age: Not specified'),
                );
              },
            );
          }
        } else {
          return CircularProgressIndicator();
        }
      },
    );
  }

  @override
  void dispose() {
    _dbManager.close();
    super.dispose();
  }
}

这个示例展示了如何使用 migrant_db_sqlite 插件来管理数据库版本和迁移。onConfigure 方法用于创建初始数据库结构,onUpgrade 方法用于处理版本升级时的数据库迁移逻辑。你可以根据需要扩展这些方法来适应不同的数据库版本和迁移需求。

回到顶部