Flutter轻量级数据库插件sembast的使用

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

Flutter轻量级数据库插件sembast的使用

sembast.dart

sembast db 代表 Simple Embedded Application Store database。它是一个为单进程IO应用程序提供的NoSQL持久化存储解决方案。整个基于文档的数据库驻留在一个文件中,并在打开时加载到内存中。更改会立即追加到文件中,当需要时文件会自动压缩。

特点

  • 纯Dart实现,支持所有平台(MacOS/Android/iOS/Linux/Windows)。
  • 支持加密,使用用户定义的编解码器。
  • 支持Web端(包括Flutter Web)通过sembast_web包。
  • 可以与sqflite一起工作通过sembast_sqflite包。

使用示例

notepad_sembast:简单的跨平台Flutter记事本应用 (在线演示)。

更多详细信息请参阅 官方指南

使用方法

打开数据库

Flutter

import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'package:sembast/sembast_io.dart';

Future<void> openDatabase() async {
  // 获取应用程序文档目录
  final dir = await getApplicationDocumentsDirectory();
  // 确保目录存在
  await dir.create(recursive: true);
  // 构建数据库路径
  final dbPath = join(dir.path, 'my_database.db');
  // 打开数据库
  final db = await databaseFactoryIo.openDatabase(dbPath);
}

Dart

// 文件路径为当前目录下的文件
String dbPath = 'sample.db';
DatabaseFactory dbFactory = databaseFactoryIo;

// 使用数据库工厂打开数据库
Database db = await dbFactory.openDatabase(dbPath);

读写记录

var store = StoreRef.main();

// 写入数据
await store.record('title').put(db, 'Simple application');
await store.record('version').put(db, 10);
await store.record('settings').put(db, {'offline': true});

// 读取数据
var title = await store.record('title').get(db) as String;
var version = await store.record('version').get(db) as int;
var settings = await store.record('settings').get(db) as Map;

// 删除记录
await store.record('version').delete(db);

Store操作

// 使用带有int键的Map记录存储动物
var store = intMapStoreFactory.store('animals');

// 存储对象
await db.transaction((txn) async {
  await store.add(txn, {'name': 'fish'});
  await store.add(txn, {'name': 'cat'});
  await store.record(10).put(txn, {'name': 'dog'});
});

// 使用主存储来存储字符串键值对
var store = StoreRef<String, String>.main();

// 写入数据
await store.record('username').put(db, 'my_username');
await store.record('url').put(db, 'my_url');

// 读取数据
var url = await store.record('url').get(db);
var username = await store.record('username').get(db);

自动递增

var store = StoreRef<int, String>.main();
// 自动递增插入
var key1 = await store.add(db, 'value1');
var key2 = await store.add(db, 'value2');
// key1 = 1, key2 = 2...

事务处理

await db.transaction((txn) async {
  await store.add(txn, 'value1');
  await store.add(txn, 'value2');
});

查询机制

var store = intMapStoreFactory.store('animals');

// 存储一些对象
await db.transaction((txn) async {
  await store.add(txn, {'name': 'fish'});
  await store.add(txn, {'name': 'cat'});
  await store.add(txn, {'name': 'dog'});
});

// 查找名称大于'cat'的动物,并按名称排序
var finder = Finder(
    filter: Filter.greaterThan('name', 'cat'),
    sortOrders: [SortOrder('name')]);
var records = await store.find(db, finder: finder);

print(records.length); // 输出: 2
print(records[0]['name']); // 输出: dog
print(records[1]['name']); // 输出: fish

监听变化

store.record(key).onSnapshots(db).listen((snapshot) {
  print(snapshot.value);
});

加密

var codec = getEncryptSembastCodec(password: '[your_user_password]');
Database db = await factory.openDatabase(dbPath, codec: codec);

示例代码

以下是一个完整的示例代码,展示了如何使用sembast进行基本的CRUD操作:

import 'dart:async';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'package:sembast/sembast.dart';
import 'package:sembast/sembast_io.dart';

Future<void> main() async {
  // 获取应用程序文档目录
  final appDocDir = await getApplicationDocumentsDirectory();
  final dbPath = join(appDocDir.path, 'record_demo.db');
  
  // 打开数据库
  final db = await databaseFactoryIo.openDatabase(dbPath);
  var store = intMapStoreFactory.store('my_store');

  // 添加记录
  var key = await store.add(db, {'name': 'ugly'});
  print('Added record with key: $key');

  // 获取记录快照
  var record = await (store.record(key).getSnapshot(db)
      as FutureOr<RecordSnapshot<int, Map<String, Object?>>>);
  print('Retrieved record: $record');

  // 查询记录
  var records = await store.find(
    db,
    finder: Finder(filter: Filter.matches('name', '^ugly'))
  );
  print('Found records: ${records.length}');
  for (var record in records) {
    print(record);
  }

  // 关闭数据库
  await db.close();
}

以上代码展示了如何创建、读取、更新和删除记录,以及如何查询特定条件的记录。希望这些信息能帮助你更好地理解和使用sembast插件。


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

1 回复

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


在Flutter项目中,sembast 是一个轻量级且功能强大的嵌入式数据库插件,它基于 SQLite 并提供了更高级的抽象层,使得在 Flutter 应用中管理本地数据更加简便。以下是一个简单的代码示例,展示了如何在 Flutter 项目中使用 sembast 插件。

1. 添加依赖

首先,在你的 pubspec.yaml 文件中添加 sembast 依赖:

dependencies:
  flutter:
    sdk: flutter
  sembast: ^x.y.z  # 替换为最新版本号

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

2. 初始化数据库

在你的 Flutter 应用中,你需要初始化数据库并打开一个存储库(store)。以下是一个简单的示例,展示了如何在应用启动时初始化数据库:

import 'package:flutter/material.dart';
import 'package:sembast/sembast.dart';
import 'package:sembast/sembast_web.dart' as sembastWeb;
import 'dart:async';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  // 使用sembastWeb.databaseFactoryIo if you are on a web platform
  final databaseFactory = sembast.databaseFactoryIo;

  // 打开或创建数据库
  final db = await databaseFactory.openDatabase('my_database.db');

  // 打开或创建存储库
  final store = StoreRef.main();

  runApp(MyApp(db, store));
}

class MyApp extends StatelessWidget {
  final Database db;
  final StoreRef store;

  MyApp(this.db, this.store);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Sembast Example'),
        ),
        body: Center(
          child: MyHomePage(db, store),
        ),
      ),
    );
  }
}

3. 插入数据

以下是一个向存储库中插入数据的示例:

class MyHomePage extends StatefulWidget {
  final Database db;
  final StoreRef store;

  MyHomePage(this.db, this.store);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  Future<void> _insertData() async {
    final record = Record<Map<String, dynamic>>({
      'name': 'Alice',
      'age': 30,
    });

    await widget.db.transaction((txn) async {
      final result = await txn.putRecord(widget.store, record);
      print('Inserted record: ${result.key}');
    });

    setState(() {}); // 刷新UI
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Text('Sembast Example'),
        ElevatedButton(
          onPressed: _insertData,
          child: Text('Insert Data'),
        ),
      ],
    );
  }
}

4. 查询数据

以下是一个从存储库中查询数据的示例:

Future<List<Map<String, dynamic>>> _queryData() async {
  List<Map<String, dynamic>> records = [];

  await widget.db.transaction((txn) async {
    final finder = Finder(sortOrders: [SortOrder('age')]);
    final results = await txn.findRecords(widget.store, finder);
    for (final record in results) {
      records.add(record.value);
    }
  });

  setState(() {}); // 刷新UI
  return records;
}

// 在你的_MyHomePageState的build方法中添加一个按钮和显示数据的部分
@override
Widget build(BuildContext context) {
  Future<List<Map<String, dynamic>>> futureRecords = _queryData();

  return Column(
    mainAxisAlignment: MainAxisAlignment.center,
    children: <Widget>[
      Text('Sembast Example'),
      ElevatedButton(
        onPressed: _insertData,
        child: Text('Insert Data'),
      ),
      ElevatedButton(
        onPressed: () async {
          final records = await futureRecords;
          // 显示查询结果,这里只是一个简单的例子,你可能需要更复杂的UI
          print('Query Results: $records');
        },
        child: Text('Query Data'),
      ),
      // 显示查询结果的简单列表
      FutureBuilder<List<Map<String, dynamic>>>(
        future: futureRecords,
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.done) {
            if (snapshot.hasError) {
              return Text('Error: ${snapshot.error}');
            } else if (snapshot.data != null) {
              return ListView.builder(
                itemCount: snapshot.data!.length,
                itemBuilder: (context, index) {
                  final record = snapshot.data![index];
                  return ListTile(
                    title: Text('Name: ${record['name']}, Age: ${record['age']}'),
                  );
                },
              );
            }
          }
          return CircularProgressIndicator();
        },
      ),
    ],
  );
}

这个示例展示了如何使用 sembast 插件在 Flutter 应用中进行基本的数据库操作,包括初始化数据库、插入数据和查询数据。你可以根据实际需求进一步扩展这些示例。

回到顶部