Flutter NoSql数据库Sembast初探

什么是Sembast?

Sembast是可用于DartVM和Fluutter的NoSql数据库。Sembast是基于文档的数据库,并且支持加密。

对于NoSql数据库的使用者来说,最大的吸引力莫过于易扩展了。相对于关系型数据库,开发者不必疲于维护数据字段或者表结构升级等繁琐的工作。尤其对于Flutter来说,作为一个客户端技术热更新技术是一直被使用者诟病的方面,所以发版前保证更新后的应用能正常使用是一个非常关键的工作,这对开发和测试团队带来了不小的挑战。比如我们常用的SqlLite数据库,一旦客户端升级过后,数据库升级带来不可逆的错误,可能导致用户必须卸载重装才能修复,这导致涉及数据库开发的功能测试一定会慎之又慎。

今天这篇文章是对NoSql数据库Sembast的使用做一个初步的探索。

Sembast特性

Yet another NoSQL persistent store database solution for single process io applications. The whole document based database resides in a single file and is loaded in memory when opened. Changes are appended right away to the file and the file is automatically compacted when needed.

Works on Dart VM and Flutter (no plugin needed, 100% Dart so works on all platforms - MacOS/Android/iOS/Linux/Windows). Inspired from IndexedDB, DataStore, WebSql, NeDB, Lawndart...

Supports encryption using user-defined codec.

Pure dart single file IO VM/Flutter storage supported.
Web support (including Flutter Web) through sembast_web.
Can work on top of sqflite through sembast_sqflite.

 这里引用官方文档介绍下Sembast特性

1. 数据库的加载方式:基于文档的单文件存储模式,打开时加载到内存,更改时会立即刷新到文件中,并且在必要时自动压缩文件。

2. 使用平台:适用于DartVM 和 Flutter,是使用纯Dart编写的无需插件的数据库,所以适用于Flutter全平台。

3. 支持使用自定义编解码器进行加密

4. 通过 sembast_web 扩展支持 Web(包括 Flutter Web)

5. 可以通过 sembast_sqflite 扩展在 sqflite 上工作

官方还提供了开源项目和在线Demo方便开发者预览效果 

开源项目地址:notepad_sembast

在线Demo预览:Web Demo

数据库使用

初始化数据库,官方示例里使用了 path_provider 扩展包来实现获取应用级目录。

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

...

// get the application documents directory
var dir = await getApplicationDocumentsDirectory();
// make sure it exists
await dir.create(recursive: true);
// build the database path
var dbPath = join(dir.path, 'my_database.db');
// open the database
var db = await databaseFactoryIo.openDatabase(dbPath);

数据库升级,使用数据库初始化版本变化时的回调来升级数据库内容

// Our shop store sample data
var store = intMapStoreFactory.store('shop');

var db = await factory.openDatabase(path, version: 1,
    onVersionChanged: (db, oldVersion, newVersion) async {
  // If the db does not exist, create some data
  if (oldVersion == 0) {
    await store.add(db, {'name': 'Lamp', 'price': 10});
    await store.add(db, {'name': 'Chair', 'price': 15});
  }
});

数据库读写

1. 获取存储对象

// dynamically typed store
var store = StoreRef.main();

2. 插入数据

// Easy to put/get simple values or map
// A key can be of type int or String and the value can be anything as long as it can
// be properly JSON encoded/decoded

// 插入String类型的记录
await store.record('title').put(db, 'Simple application');
// 插入int类型的记录
await store.record('version').put(db, 10);
// 插入Map类型的记录
await store.record('settings').put(db, {'offline': true});

3. 读取数据

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;

4. 删除记录

await store.record('version').delete(db);


版权声明:本文为songchao8868原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。