最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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 本質上就是將鍵值對保存到一個XML文件中進行持久化。

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

SQLite是關系型數(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)了一個獨立的、無服務器、零配置、事務性的nosql數(shù)據(jù)庫引擎。它是一個文檔存儲數(shù)據(jù)庫,類似于MongoDB, Redis, CouchDB等,同時也是一個標準的key/value存儲數(shù)據(jù)庫,類似于BerkeleyDB, LevelDB, 等。

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

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

unqlite_flutter

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

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

當然,這里我已經(jīng)完成了Dart FFI調用的封裝,可以直接依賴我開發(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}');

你還可以使用事務。在一個事務中,如果發(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) {
      // 處理異常,手動回滾事務
      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();

為什么你應該使用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)容,更多關于Flutter鍵值存儲數(shù)據(jù)庫的資料請關注腳本之家其它相關文章!

相關文章

  • 簡單談談android studio 的單元測試

    簡單談談android studio 的單元測試

    昨天在完善項目的時候,需要進行單元測試,在Eclipse環(huán)境中進行是很簡單的,但是在Android Studio環(huán)境中進行單元測試,在國內(nèi)找了很多資料,大都是人云亦云,本文發(fā)布出來供大家學習參考。
    2016-08-08
  • Android?Gradle?三方依賴管理詳解

    Android?Gradle?三方依賴管理詳解

    這篇文章主要介紹了Android?Gradle?三方依賴管理詳解,Gradle的依賴管理是一個從開始接觸Android開發(fā)就一直伴隨著我們的問題,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的朋友可以參考一下
    2022-08-08
  • Android 中LayoutInflater.inflate()方法的介紹

    Android 中LayoutInflater.inflate()方法的介紹

    這篇文章主要介紹了Android 中LayoutInflater.inflate()方法的介紹的相關資料,希望通過本文大家能掌握這部分內(nèi)容,需要的朋友可以參考下
    2017-09-09
  • Android 斷點下載和自動安裝的示例代碼

    Android 斷點下載和自動安裝的示例代碼

    本篇文章主要介紹了Android斷點下載和自動安裝的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-01-01
  • Android中代碼運行指定Apk的簡單方法

    Android中代碼運行指定Apk的簡單方法

    這篇文章主要介紹了Android中代碼運行指定Apk的簡單方法,有需要的朋友可以參考一下
    2014-01-01
  • Android Studio獲取配置資源與第三方包信息的方法

    Android Studio獲取配置資源與第三方包信息的方法

    在 Android 開發(fā)中,我們經(jīng)常需要從資源文件中獲取顏色、字符串、數(shù)值等配置信息,以及獲取應用的包信息和第三方依賴信息,下面詳細介紹這些操作的方法,需要的朋友可以參考下
    2025-04-04
  • kotlin中的模塊化結構組件及工作原理

    kotlin中的模塊化結構組件及工作原理

    本文介紹了Kotlin中模塊化結構組件,包括ViewModel、LiveData、Room和Navigation的工作原理和基礎使用,本文通過實例代碼給大家介紹的非常詳細,感興趣的朋友一起看看吧
    2025-03-03
  • Android實現(xiàn)四級聯(lián)動地址選擇器

    Android實現(xiàn)四級聯(lián)動地址選擇器

    這篇文章主要為大家詳細介紹了Android實現(xiàn)四級聯(lián)動地址選擇器,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-10-10
  • 解決Android popupWindow設置背景透明度無效的問題

    解決Android popupWindow設置背景透明度無效的問題

    這篇文章主要介紹了解決Android popupWindow設置背景透明度無效的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • Android webveiw 出現(xiàn)棧錯誤解決辦法

    Android webveiw 出現(xiàn)棧錯誤解決辦法

    這篇文章主要介紹了Android webveiw 出現(xiàn)棧錯誤解決辦法的相關資料,出現(xiàn)java.lang.UnsupportedOperationException: For security reasons, WebView is not allowed in privileged processes,這里提供解決辦法,需要的朋友可以參考下
    2017-08-08

最新評論

株洲县| 齐河县| 都昌县| 南溪县| 平顶山市| 霍山县| 明水县| 扬州市| 吴桥县| 黄龙县| 布尔津县| 张家口市| 从江县| 陈巴尔虎旗| 二连浩特市| 瑞昌市| 改则县| 调兵山市| 图木舒克市| 巴南区| 门头沟区| 津市市| 怀集县| 阜康市| 左权县| 黄骅市| 吉水县| 綦江县| 确山县| 靖安县| 含山县| 杨浦区| 黄骅市| 阳朔县| 固镇县| 同心县| 胶州市| 房产| 钟山县| 崇礼县| 芦溪县|