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

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

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

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

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

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

SQLite是關(guān)系型數(shù)據(jù)庫,使用起來相對(duì)繁瑣;而Hive是用Dart實(shí)現(xiàn)的一個(gè)輕量級(jí)鍵值對(duì)數(shù)據(jù)庫,它使用簡(jiǎn)單,但同樣性能較差,而且在儲(chǔ)存大量數(shù)據(jù)時(shí),更加耗費(fèi)內(nèi)存,因?yàn)樗且淮涡詫⑺袛?shù)據(jù)讀取到內(nèi)存中,這在移動(dòng)端不是很可取。當(dāng)然,如果你只是用來存儲(chǔ)幾個(gè)簡(jiǎn)單的配置項(xiàng)數(shù)據(jù),那也夠用了。

unqlite

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

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

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

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

unqlite_flutter

既然unqlite是一個(gè)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)為我所用!想學(xué)習(xí)Flutter的FFI開發(fā),可以參考博主的B站視頻 Dart FFI開發(fā)入門 以及 程序員的C

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

目前已完成的功能:

  • key-value 儲(chǔ)存
  • JSON 文檔儲(chǔ)存

快速上手

簡(jiǎn)單鍵值對(duì)存儲(chǔ)

添加依賴:

  unqlite: ^0.0.3
  unqlite_flutter: ^0.0.3

示例代碼:

// 創(chuàng)建或打開一個(gè)數(shù)據(jù)庫
UnQLite db = UnQLite.open("${appDocDir.path}/test.db");
// 保存鍵值對(duì)
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');
});

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

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

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

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

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

你還可以使用迭代器來進(jìn)行遍歷:

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 文檔

它有什么缺點(diǎn)? 因?yàn)槭褂昧薲art ffi,所以不能支持Flutter web。

下面是一些性能測(cè)試數(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

這是用于測(cè)試的代碼,兩者都在同一部真機(jī)上以profile模式運(yùn)行:

    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的鍵值存儲(chǔ)數(shù)據(jù)庫使用示例詳解的詳細(xì)內(nèi)容,更多關(guān)于Flutter鍵值存儲(chǔ)數(shù)據(jù)庫的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 簡(jiǎn)單談?wù)刟ndroid studio 的單元測(cè)試

    簡(jiǎn)單談?wù)刟ndroid studio 的單元測(cè)試

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

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

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

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

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

    Android 斷點(diǎn)下載和自動(dòng)安裝的示例代碼

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

    Android中代碼運(yùn)行指定Apk的簡(jiǎn)單方法

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

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

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

    kotlin中的模塊化結(jié)構(gòu)組件及工作原理

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

    Android實(shí)現(xiàn)四級(jí)聯(lián)動(dòng)地址選擇器

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

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

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

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

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

最新評(píng)論

本溪| 青神县| 龙井市| 梨树县| 宣城市| 德庆县| 杭州市| 鸡西市| 宁海县| 黑河市| 大田县| 灵石县| 昌江| 凤山市| 深州市| 闽侯县| 固安县| 白河县| 宜昌市| 廊坊市| 禄丰县| 济源市| 安徽省| 酉阳| 深圳市| 固镇县| 宁乡县| 英超| 河池市| 阿克| 美姑县| 阿巴嘎旗| 盐山县| 长汀县| 桂平市| 新营市| 塔河县| 田阳县| 辉南县| 嘉鱼县| 阿克陶县|