Flutter数据库抽象层插件idb_shim的使用

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

Flutter数据库抽象层插件idb_shim的使用

idb_shim 是一个纯Dart编写的Indexed DB风格API,旨在为Flutter应用提供跨平台的数据库解决方案。它在不同平台上有着不同的实现方式:

  • 在Web端(Wasm兼容,使用 dart:js_interop),它是基于IndexedDB Web API的一个轻量级封装。
  • 在IO端(包括桌面和移动设备)以及内存中,提供了基于Sembast的实现,这使得开发者可以在测试环境中方便地模拟真实的数据访问场景。

一、基本用法

1. 替换原有的IndexedDB代码

如果你已经有一个使用IndexedDB的应用,可以将如下代码:

import 'dart:indexed_db';
window.indexedDB.open(dbName, version: xxx, onUpgradeNeeded: yyy);

替换为:

import 'package:idb_shim/idb_browser.dart'
IdbFactory idbFactory = getIdbFactory();
idbFactory.open(dbName, version: xxx, onUpgradeNeeded: yyy);

2. 示例代码

下面是一个简单的示例,展示了如何打开数据库、创建对象存储区、插入数据并读取数据:

// 定义存储区名称
const String storeName = "records";

// 打开数据库
Database db = await idbFactory.open("my_records.db", version: 1,
    onUpgradeNeeded: (VersionChangeEvent event) {
  Database db = event.database;
  // 创建存储区
  db.createObjectStore(storeName, autoIncrement: true);
});

// 插入数据
var txn = db.transaction(storeName, "readwrite");
var store = txn.objectStore(storeName);
var key = await store.put({"some": "data"});
await txn.completed;

// 读取数据
txn = db.transaction(storeName, "readonly");
store = txn.objectStore(storeName);
Map value = await store.getObject(key);
await txn.completed;

print(value);

二、Flutter支持

对于Flutter项目来说,虽然可以直接使用idb_shim结合sembast来作为后端存储方案,但也有专门针对移动端(iOS和Android)的实现——idb_sqflite,该实现基于sqflite库。

三、注意事项

  1. 调试时保持相同的Web端口:由于浏览器中的IndexedDB与端口绑定,在调试过程中应确保使用相同端口以维持同一份数据库实例。
  2. 类型限制:支持JSON序列化/反序列化的类型(如numStringbool等),并且从版本1.11开始增加了对DateTimeUint8List的支持。但是需要注意的是,循环引用不被支持,并且不要尝试在一个布尔值上建立索引。
  3. 键类型的限制:只支持字符串和数字(整数或浮点数)作为键值。

四、完整示例Demo

为了更好地理解idb_shim的实际应用,以下是一个完整的示例demo,演示了如何在Flutter项目中使用idb_shim进行数据持久化操作。

示例代码

// ignore_for_file: avoid_print

import 'package:idb_shim/idb_io.dart';

void main() async {
  final idbFactory = getIdbFactoryPersistent('test/tmp/out');

  // 定义存储区名称
  final storeName = 'records';

  // 打开数据库
  final db = await idbFactory.open('my_records.db', version: 1,
      onUpgradeNeeded: (VersionChangeEvent event) {
    final db = event.database;
    // 创建存储区
    db.createObjectStore(storeName, autoIncrement: true);
  });

  // 插入数据
  var txn = db.transaction(storeName, idbModeReadWrite);
  var store = txn.objectStore(storeName);
  var key = await store.put({'some': 'data'});
  await txn.completed;

  // 读取数据
  txn = db.transaction(storeName, idbModeReadOnly);
  store = txn.objectStore(storeName);
  final value = await store.getObject(key) as Map;
  await txn.completed;

  print(value);
}

这个例子展示了如何在Flutter应用程序中使用idb_shim来进行简单的CRUD操作。通过这种方式,你可以轻松地在多个平台上实现一致的数据存储逻辑。


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

1 回复

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


在Flutter项目中,使用idb_shim库可以为你提供一个跨平台的数据库抽象层,它支持多种数据库后端,包括IndexedDB(仅限Web平台)、LevelDB(在桌面和移动平台上通过levelupleveldown的shim实现)、SQLite等。这对于开发需要持久化存储的跨平台应用非常有用。

以下是一个简单的示例,展示了如何在Flutter项目中使用idb_shim库进行基本的数据库操作,包括创建数据库、打开对象存储、添加和读取数据。

1. 添加依赖

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

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

然后运行flutter pub get来安装依赖。

2. 配置数据库

由于idb_shim支持多种后端,你需要根据你的目标平台选择适当的配置。以下是一个基本的配置示例,使用LevelDB作为后端:

import 'package:idb_shim/indexed_db_shim.dart';
import 'package:idb_shim/impls/databases/leveldb_db.dart';
import 'dart:typed_data';

Future<Database> initDatabase() async {
  // 配置LevelDB
  var factory = new LevelDBFactory();
  var dbPath = (await getApplicationDocumentsDirectory()).path + '/my_database';
  var leveldb = await factory.openDatabase(dbPath);

  // 使用idb_shim的封装
  var idbFactory = getIdbFactory(
    dbNames: ['my_database'],
    objectStores: [
      ObjectStoreSpec.make('my_store', keyPath: 'id', autoIncrement: true),
    ],
    name: 'my_database',
    version: 1,
    backend: IdbFactoryBackend.LEVELDB,
    leveldb: leveldb,
  );

  var db = await idbFactory.openDatabase('my_database', 1);
  return db;
}

3. 执行数据库操作

一旦数据库初始化完成,你就可以执行数据库操作了。以下是一个添加和读取数据的示例:

import 'dart:async';
import 'dart:typed_data';

Future<void> main() async {
  Database db = await initDatabase();

  // 添加数据
  var transaction = db.transaction(['my_store'], 'readwrite');
  var objectStore = transaction.objectStore('my_store');
  var request = objectStore.add({'name': 'Alice', 'age': 30});

  request.onsuccess = (event) {
    print('Data added with key: ${request.result}');
  };

  request.onerror = (event) {
    print('Error adding data: ${request.error}');
  };

  await transaction.done;

  // 读取数据
  transaction = db.transaction(['my_store']);
  objectStore = transaction.objectStore('my_store');
  var keyRange = IdbKeyRange.only(request.result); // 使用之前添加的键
  var getAllRequest = objectStore.getAll(keyRange);

  getAllRequest.onsuccess = (event) {
    var results = getAllRequest.result;
    results.forEach((result) {
      print('Data retrieved: ${result}');
    });
  };

  getAllRequest.onerror = (event) {
    print('Error retrieving data: ${getAllRequest.error}');
  };

  await transaction.done;
}

注意

  • 上述代码是一个简化的示例,实际项目中你可能需要处理更多的错误和边界情况。
  • idb_shim的配置和使用可能会随着库的更新而变化,请参考最新的官方文档获取最新信息。
  • 对于Web平台,你可能需要使用IndexedDB作为后端,并相应地调整配置代码。

这个示例展示了如何在Flutter中使用idb_shim库进行基本的数据库操作。根据你的应用需求,你可以进一步扩展这些操作,比如更新和删除数据。

回到顶部