Flutter数据库管理插件sqlite3_test的使用

Flutter数据库管理插件sqlite3_test的使用

该包提供了在Dart测试中访问SQLite数据库的工具。

功能

由于SQLite没有任何外部依赖,并且运行在你的应用程序进程中,因此它可以在单元测试中轻松使用(避免了为数据库和存储库编写模拟对象的麻烦)。

然而,作为C库,SQLite不知道通常在测试中使用的其他Dart工具(如package:clock的虚拟时间或基于package:file的自定义文件系统)。当你数据库查询依赖于CURRENT_TIMESTAMP时,这使得可靠地测试它们变得困难,因为clock.now()CURRENT_TIMESTAMP会报告不同的值。

作为解决方案,这个小包通过提供一个VFS(虚拟文件系统)使SQLite更容易集成到你的测试中。这个VFS将:

  1. 使CURRENT_TIMECURRENT_DATECURRENT_TIMESTAMP反映由package:clock返回的时间。
  2. 对于I/O操作,允许提供来自package:fileFileSystem。这包括自定义实现和尊重IOOverrides的默认实现。

使用方法

该包主要用于测试,所以首先你需要在项目中添加一个开发依赖项:

$ dart pub add --dev sqlite3_test

然后,你可以在测试中使用它,通过创建一个用于数据库的TestSqliteFileSystem实例:

import 'package:fake_async/fake_async.dart';
import 'package:sqlite3/sqlite3.dart';
import 'package:sqlite3_test/sqlite3_test.dart';
import 'package:file/local.dart';
import 'package:test/test.dart';

void main() {
  late TestSqliteFileSystem vfs;

  setUpAll(() {
    vfs = TestSqliteFileSystem(fs: const LocalFileSystem());
    sqlite3.registerVirtualFileSystem(vfs);
  });

  tearDownAll(() => sqlite3.unregisterVirtualFileSystem(vfs));

  test('我的测试依赖于数据库时间', () {
    final database = sqlite3.openInMemory(vfs: vfs.name);
    addTearDown(database.dispose);

    // VFS使用package:clock获取当前时间,可以在测试中覆盖:
    final moonLanding = DateTime.utc(1969, 7, 20, 20, 18, 04);
    FakeAsync(initialTime: moonLanding).run((_) {
      final row = database.select('SELECT unixepoch(current_timestamp)').first;

      expect(row.columnAt(0), -14182916);
    });
  });
}

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

1 回复

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


在Flutter中,sqlite3_test 并不是一个官方或广泛使用的插件来管理SQLite数据库。通常,开发者会使用更流行和成熟的插件,如 sqflite,来进行SQLite数据库操作。不过,假设你提到的 sqlite3_test 是一个自定义的或特定项目的插件,并且你已经配置好了Flutter项目来使用它,这里是一个基本的示例,展示如何使用一个SQLite数据库插件进行基本的CRUD(创建、读取、更新、删除)操作。

由于sqlite3_test不是标准插件,我将以sqflite为例来展示,但你可以根据sqlite3_test的API进行相应的调整。

使用 sqflite 插件进行数据库操作的示例

首先,确保你的pubspec.yaml文件中包含sqflite依赖:

dependencies:
  flutter:
    sdk: flutter
  sqflite: ^2.0.0+4  # 请检查最新版本号

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

数据库帮助类

创建一个帮助类来管理数据库操作:

import 'package:sqflite/sqflite.dart';
import 'package:path_provider/path_provider.dart';

class DatabaseHelper {
  static final DatabaseHelper _instance = DatabaseHelper._internal();

  factory DatabaseHelper() => _instance;

  DatabaseHelper._internal();

  Database? _database;

  Future<Database> get database async {
    if (_database != null) return _database!;

    // 获取应用的文档目录
    Directory documentsDirectory = await getApplicationDocumentsDirectory();
    String path = join(documentsDirectory.path, 'my_database.db');

    // 打开(或创建)数据库
    _database = await openDatabase(path, version: 1, onCreate: _onCreate);

    return _database!;
  }

  Future _onCreate(Database db, int version) async {
    // 当数据库首次创建时,创建表
    await db.execute('''
      CREATE TABLE users (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT NOT NULL,
        age INTEGER NOT NULL
      )
    ''');
  }

  // 插入数据
  Future<void> insertUser(String name, int age) async {
    final Database db = await database;
    await db.insert('users', {'name': name, 'age': age});
  }

  // 查询所有数据
  Future<List<Map<String, dynamic>>> getAllUsers() async {
    final Database db = await database;
    return await db.query('users');
  }

  // 更新数据
  Future<void> updateUser(int id, String name, int age) async {
    final Database db = await database;
    await db.update('users', {'name': name, 'age': age}, where: 'id = ?', whereArgs: [id]);
  }

  // 删除数据
  Future<void> deleteUser(int id) async {
    final Database db = await database;
    await db.delete('users', where: 'id = ?', whereArgs: [id]);
  }
}

使用数据库帮助类

在你的Flutter应用中,你可以这样使用这个帮助类:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('SQLite Demo'),
        ),
        body: MyHomePage(),
      ),
    );
  }
}

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

class _MyHomePageState extends State<MyHomePage> {
  DatabaseHelper _databaseHelper = DatabaseHelper();

  @override
  void initState() {
    super.initState();
    _insertSomeData();
  }

  Future<void> _insertSomeData() async {
    await _databaseHelper.insertUser('Alice', 30);
    await _databaseHelper.insertUser('Bob', 25);
  }

  Future<void> _readAllData() async {
    List<Map<String, dynamic>> users = await _databaseHelper.getAllUsers();
    print(users);
    // 可以在这里更新UI来显示用户数据
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          ElevatedButton(
            onPressed: _readAllData,
            child: Text('Read All Users'),
          ),
        ],
      ),
    );
  }
}

注意

  • 如果你确实使用的是sqlite3_test插件,请查阅该插件的文档或源代码来了解其特定的API和用法。
  • 上述代码是基于sqflite插件的示例,但大多数SQLite插件的API设计都是相似的,包括打开数据库、创建表、执行CRUD操作等。
  • 确保处理异常和错误,特别是在进行数据库操作时,以提供健壮的用户体验。
回到顶部