欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Flutter的鍵值存儲數(shù)據(jù)庫使用示例詳解

 更新時間:2022年08月08日 08:52:45   作者:編程之路從0到1  
這篇文章主要為大家介紹了Flutter的鍵值存儲數(shù)據(jù)庫使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

Flutter 鍵值存儲數(shù)據(jù)庫

鍵值存儲是開發(fā)中十分常見的需求,在Flutter開發(fā)中,一般使用 shared_preferences 插件來實現(xiàn)。shared_preferences 本質(zhì)上就是將鍵值對保存到一個XML文件中進行持久化。

而shared_preferences 實際上存在一定缺陷,譬如其性能較差,不適合處理大量數(shù)據(jù),不能創(chuàng)建新的XML文件,所有數(shù)據(jù)存在同一個文件中。除此外,還有其他一些持久化方案,如SQLite、Hive等。

SQLite是關(guān)系型數(shù)據(jù)庫,使用起來相對繁瑣;而Hive是用Dart實現(xiàn)的一個輕量級鍵值對數(shù)據(jù)庫,它使用簡單,但同樣性能較差,而且在儲存大量數(shù)據(jù)時,更加耗費內(nèi)存,因為它是一次性將所有數(shù)據(jù)讀取到內(nèi)存中,這在移動端不是很可取。當然,如果你只是用來存儲幾個簡單的配置項數(shù)據(jù),那也夠用了。

unqlite

以上概述了一下Flutter的鍵值持久化方案,那么接下來就隆介紹一下本文推薦的Flutter鍵值存儲方案——一個輕量級嵌入式nosql數(shù)據(jù)庫unqlite!

unqlite是一個嵌入式的數(shù)據(jù)庫,它實現(xiàn)了一個獨立的、無服務(wù)器、零配置、事務(wù)性的nosql數(shù)據(jù)庫引擎。它是一個文檔存儲數(shù)據(jù)庫,類似于MongoDB, Redis, CouchDB等,同時也是一個標準的key/value存儲數(shù)據(jù)庫,類似于BerkeleyDB, LevelDB, 等。

  • 首先unqlite是一個無服務(wù)器的數(shù)據(jù)庫,這意味著它的通訊是直接讀取數(shù)據(jù)庫文件的(從磁盤讀?。?,沒有中間服務(wù)器進程。
  • 然后unqlite也不像其他服務(wù)器一樣,需要安裝、配置以及權(quán)限管理等。它是直接嵌入到我們的程序中的
  • unqlite是一個單一數(shù)據(jù)庫文件,它的數(shù)據(jù)庫是一個普通的磁盤文件。這就意味著你可以把它隨意的復制或備份到其他地方。
  • unqlite文件格式是跨平臺的。在一臺機器上編寫的數(shù)據(jù)庫文件可以復制到具有不同體系結(jié)構(gòu)的不同機器上并在其上使用。
  • unqlite是一個標準的鍵/值存儲數(shù)據(jù)庫,類似于BerkeleyDB,Tokyo Cabinet,LevelDB等,但具有豐富的功能集,包括對事務(wù)的支持(ACID)。在KV存儲下,鍵和值都被視為簡單的字節(jié)數(shù)組,因此內(nèi)容可以是ASCII字符串,二進制blob甚至磁盤文件。

簡單概括,unqlite是一個標準C語言實現(xiàn)的輕量級、高性能nosql數(shù)據(jù)庫,經(jīng)過編譯后,它只有幾百KB大小,可以嵌入到我們的App中,它與SQLite數(shù)據(jù)庫類似,區(qū)別在于一個是基于SQL的關(guān)系型數(shù)據(jù)庫,一個是NoSql數(shù)據(jù)庫。

unqlite_flutter

既然unqlite是一個C語言編寫的數(shù)據(jù)庫,那么Flutter開發(fā)如何使用它呢?

隨著Dart版本的不斷迭代,Dart語言的FFI接口逐漸成熟,F(xiàn)FI類似于Java的JNI,賦予了Dart語言直接調(diào)用C語言的能力。有了這種能力,那么基于C/C++開發(fā)的優(yōu)秀的高性能的庫,都可以用于Flutter開發(fā)中,可以說是C/C++生態(tài)為我所用!想學習Flutter的FFI開發(fā),可以參考博主的B站視頻 Dart FFI開發(fā)入門 以及 程序員的C

當然,這里我已經(jīng)完成了Dart FFI調(diào)用的封裝,可以直接依賴我開發(fā)好的插件庫——unqlite_flutter

目前已完成的功能:

  • key-value 儲存
  • JSON 文檔儲存

快速上手

簡單鍵值對存儲

添加依賴:

  unqlite: ^0.0.3
  unqlite_flutter: ^0.0.3

示例代碼:

// 創(chuàng)建或打開一個數(shù)據(jù)庫
UnQLite db = UnQLite.open("${appDocDir.path}/test.db");
// 保存鍵值對
db.store("name", "Alex");
db.store("age", 18);
db.store(19, "haha");
// 通過指定泛型獲取值
debugPrint(db.fetch<String>("name"));
debugPrint('${db.fetch<int>("age")}');
debugPrint(db.fetch<String>(19));
// 另一種獲取值的方法
db.fetchCallback<int>("age", (val) {
    debugPrint('age=$val');
});

當然,還有另一種獲取數(shù)據(jù)的方式,可能比fetch更快:

var cursor = db.cursor();
cursor.seek('name');
debugPrint('=> ${cursor.key} => ${cursor.value}');

你還可以使用事務(wù)。在一個事務(wù)中,如果發(fā)生異常,你可以回滾所有操作:

    var trans = db.transaction().begin();
    try {
      for (var i = 0; i < 100000; i++) {
        if (i == 10) {
          // 這里我們拋出一個異常
          throw Exception('test');
        }
        db.store("transaction_$i", "here is a transaction_$i");
      }
      trans.commit();
    } catch (e) {
      // 處理異常,手動回滾事務(wù)
      trans.rollback();
    }

以上示例中,我們保存十萬個數(shù)據(jù),一旦中間發(fā)生了什么異常,我們執(zhí)行回滾操作,則前面所有的保存的數(shù)據(jù)將被取消。

你還可以使用迭代器來進行遍歷:

for (var entry in db.cursor()) {
  var content = '${entry.key} => ${entry.value}';
  debugPrint(content);
}

JSON

處理JSON文檔

    UnQLite db = UnQLite.open("${appDocDir.path}/test2.db");
    var users = db.collection("users");
	// Create a collection
    users.create();
	// 保存JSON
    users.store(jsonDecode('''
{
        "title": "test json string",
        "author": [
                "arcticfox1919"
        ],
        "year": 2022,
        "like": "flutter"
}
    '''));
    users.store({'name': 'Mickey', 'age': 17});
    users.store([
      {'name': 'Alice', 'age': 18},
      {'name': 'Bruce', 'age': 19},
      {'name': 'Charlie', 'age': 20},
    ]);
	// 獲取全部數(shù)據(jù)
    print(users.all());
    // print(users.fetch(0));
    // print(users.fetch(1));
    // print(users.fetch(2));
    // print(users.errorLog());
    print(users.creationDate());
    print(users.len());
    print(users.fetchCurrent());
    // 刪除全部
    users.drop();
    db.close();

為什么你應(yīng)該使用unqlite_flutter?

  • 比 Hive 更快,占用更少的內(nèi)存
  • 可以支持 JSON 文檔

它有什么缺點? 因為使用了dart ffi,所以不能支持Flutter web。

下面是一些性能測試數(shù)據(jù),這里沒有列出內(nèi)存占用的百分比,但可以肯定 unqlite 比Hive 使用了更少的內(nèi)存:

UnQLite:

UnQLite init:1 ms
write 100,000 entries :611 ms
fetch 100,000 entries :370 ms
seek  100,000 entries :215 ms
iterate 100,000 entries :225 ms
transaction rollback :39 ms

Hive:

Hive init:48 ms
put 100,000 entries :807 ms
get 100,000 entries :290 ms

這是用于測試的代碼,兩者都在同一部真機上以profile模式運行:

    testUnQLite() async {
    var appDocDir = await getApplicationDocumentsDirectory();
    final start = DateTime.now().millisecondsSinceEpoch;
    UnQLite db = UnQLite.open("${appDocDir.path}/test.db");
    final t1 = DateTime.now().millisecondsSinceEpoch;
    for (var i = 0; i < 100000; i++) {
      db.store("my_key_$i", "Here is a value for testing—$i");
    }
    final t2 = DateTime.now().millisecondsSinceEpoch;
    for (var i = 0; i < 100000; i++) {
      var r = db.fetch<String>("my_key_$i");
      // debugPrint("fetch :$r");
    }
    final t3 = DateTime.now().millisecondsSinceEpoch;
    var cursor = db.cursor();
    for (var i = 0; i < 100000; i++) {
      cursor.seek('my_key_$i');
      // debugPrint('=> ${cursor.key} => ${cursor.value}');
    }
    final t4 = DateTime.now().millisecondsSinceEpoch;
    var count = 0;
    for (var entry in db.cursor()) {
      count++;
      var content = '${entry.key} => ${entry.value}';
      // debugPrint(content);
    }
    print('count => $count');
    final t5 = DateTime.now().millisecondsSinceEpoch;
    var trans = db.transaction().begin();
    try {
      for (var i = 0; i < 100000; i++) {
        if (i == 10) {
          throw Exception('test');
        }
        db.store("transaction_$i", "here is a transaction_$i");
      }
      trans.commit();
    } catch (e) {
      trans.rollback();
    }
    final t6 = DateTime.now().millisecondsSinceEpoch;
    debugPrint("UnQLite init:${t1-start} ms");
    debugPrint("write 100,000 entries :${t2-t1} ms");
    debugPrint("fetch 100,000 entries :${t3-t2} ms");
    debugPrint("seek  100,000 entries :${t4-t3} ms");
    debugPrint("iterate 100,000 entries :${t5-t4} ms");
    debugPrint("transaction rollback :${t6-t5} ms");
    db.close();
  }
  testHive() async {
    var appDocDir = await getApplicationDocumentsDirectory();
    var path = appDocDir.path;
    final start = DateTime.now().millisecondsSinceEpoch;
    Hive.init(path);
    var box = await Hive.openBox('testBox');
    final t1 = DateTime.now().millisecondsSinceEpoch;
    for (var i = 0; i < 100000; i++) {
      box.put("my_key_$i", "here is a transaction_$i");
    }
    final t2 = DateTime.now().millisecondsSinceEpoch;
    for (var i = 0; i < 100000; i++) {
      var name = box.get('my_key_$i');
    }
    final t3 = DateTime.now().millisecondsSinceEpoch;
    box.close();
    debugPrint("Hive init:${t1-start} ms");
    debugPrint("put 100,000 entries :${t2-t1} ms");
    debugPrint("get 100,000 entries :${t3-t2} ms");
  }

以上就是Flutter的鍵值存儲數(shù)據(jù)庫使用示例詳解的詳細內(nèi)容,更多關(guān)于Flutter鍵值存儲數(shù)據(jù)庫的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論