Flutter Hive NoSql 數(shù)據(jù)庫使用指南

Flutter Hive NoSql 數(shù)據(jù)庫使用指南

視頻

https://www.bilibili.com/video/BV1yJ4m1u7P2/

https://youtu.be/UJobRKdp68k

前言

原文 https://ducafecat.com/blog/flutter-hive-nosql-guide

本文將會寫一個 Hive CURD 的例子蜗侈,詳細介紹 Hive 這個輕量級的 Flutter 離線數(shù)據(jù)庫的使用方法,包括 Hive 在 Flutter 開發(fā)中的重要性奖地、Hive 與 SQLite 的比較等,幫助開發(fā)者快速上手 Hive 數(shù)據(jù)庫蒋譬。

Flutter, Hive, NoSql, 離線數(shù)據(jù)庫, 鍵值對數(shù)據(jù)庫, 跨平臺開發(fā)

參考

https://docs.hivedb.dev/#/

https://pub.dev/packages/hive

Hive

Hive 是一個 nosql 的離線數(shù)據(jù)庫颂翼,在 Flutter 開發(fā)中具有重要的作用柏肪。以下是 Hive 在 Flutter 開發(fā)中的一些重要性:

  • 離線數(shù)據(jù)存儲: Hive 提供了一個高性能的鍵值對數(shù)據(jù)庫,可以在用戶設備上存儲大量的離線數(shù)據(jù)。這對于需要離線使用的應用程序非常有用,例如社交應用岭洲、閱讀應用等苦始。

  • 快速讀寫: Hive 基于 Dart 的二進制序列化,讀寫速度非程兀快。這對于需要頻繁讀寫數(shù)據(jù)的應用程序來說非常重要,可以提高用戶體驗吭净。

  • 跨平臺支持: Hive 同時支持 Android 和 iOS 平臺,可以在不同操作系統(tǒng)上無縫使用,大大降低了跨平臺開發(fā)的成本睡汹。

  • 簡單易用: Hive 的 API 設計得非常簡潔明了,上手容易,可以快速集成到 Flutter 項目中。

  • 數(shù)據(jù)安全: Hive 提供了數(shù)據(jù)加密功能,可以保護用戶的隱私數(shù)據(jù)安全寂殉。

  • 與 Flutter 集成良好: Hive 與 Flutter 集成非常好,可以完美地與 Flutter 的狀態(tài)管理等其他功能配合使用囚巴。

Hive 與 SQLite 比較

  • 數(shù)據(jù)存儲方式:
    • Hive: Hive 是一個基于 Key-Value 的 NoSQL 數(shù)據(jù)庫,數(shù)據(jù)以二進制形式存儲在本地文件中。
    • SQLite: SQLite 是一個基于 SQL 語言的關系型數(shù)據(jù)庫,數(shù)據(jù)以表格形式存儲在本地數(shù)據(jù)庫文件中友扰。
  • 查詢方式:
    • Hive: Hive 采用類似 Map 的 API 進行數(shù)據(jù)的增刪改查,比如 get(), put(), delete()等彤叉。
    • SQLite: SQLite 采用 SQL 語言進行數(shù)據(jù)的增刪改查,比如 SELECT, INSERT, UPDATE, DELETE等。
  • 性能:
    • Hive: Hive 的讀寫性能普遍優(yōu)于 SQLite,因為 Hive 的數(shù)據(jù)操作更加簡單高效村怪。
    • SQLite: SQLite 在處理復雜的查詢和關聯(lián)操作時,性能可能會略優(yōu)于 Hive秽浇。
  • 查詢復雜度:
    • Hive: Hive 的查詢相對簡單,更適合一些基本的數(shù)據(jù)存儲和訪問需求。
    • SQLite: SQLite 支持復雜的 SQL 查詢,可以處理更加復雜的數(shù)據(jù)關系和業(yè)務需求甚负。
  • 數(shù)據(jù)庫結構:
    • Hive: Hive 的數(shù)據(jù)結構相對簡單,主要是 Key-Value 形式柬焕。
    • SQLite: SQLite 支持更加復雜的數(shù)據(jù)庫結構,包括表、索引梭域、視圖等击喂。
  • 數(shù)據(jù)類型:
    • Hive: Hive 支持基本的數(shù)據(jù)類型,比如 int、string碰辅、bool等。
    • SQLite: SQLite 支持更豐富的數(shù)據(jù)類型,包括 int介时、float没宾、text、blob等沸柔。

Hive 與 shared_preferences 比較

  • Hive

    • NoSQL 數(shù)據(jù)庫

    • 快速高效

    • 支持加密

    • 將數(shù)據(jù)存儲在箱中(類似于表)

    • 支持事務

    • 有更大的存儲容量

  • Shared Preferences

    • 鍵值存儲

    • 簡單易用

    • 將數(shù)據(jù)存儲在映射中(鍵值對)

    • 不支持事務

    • 存儲容量有限

  • 使用場景:

    • Hive: 適合大量結構化數(shù)據(jù)循衰,如用戶信息、應用程序設置和游戲數(shù)據(jù)褐澎。

    • Shared Preferences: 適合少量簡單數(shù)據(jù)会钝,如用戶偏好、令牌和標志工三。

實現(xiàn)步驟

第一步:初始

包依賴 pubspec.yaml

dependencies:
  hive: 2.2.3
  hive_flutter: 1.1.0

初始 hive 對象 lib/main.dart

Future<void> main() async {
  await Hive.initFlutter();
  runApp(const MyApp());
}

第二步:新增

lib/utils.dart

工具類迁酸,模擬數(shù)據(jù)用

import 'dart:math';

// 隨機字符串函數(shù)
String generateRandomString() {
  final rnd = Random.secure();
  final length = 8 + rnd.nextInt(5); // 生成 8 到 12 位之間的隨機長度
  const chars =
      'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz1234567890';

  return String.fromCharCodes(
    Iterable.generate(
      length,
      (_) => chars.codeUnitAt(rnd.nextInt(chars.length)),
    ),
  );
}
// 隨機編號函數(shù)
String generateRandomNumberString() {
  final rnd = Random.secure();
  final prefix = rnd.nextInt(90) + 10; // 生成 10 到 99 之間的前綴
  final suffix = rnd.nextInt(9000) + 1000; // 生成 1000 到 9999 之間的后綴

  return '$prefix$suffix';
}

lib/page.dart

成員變量

  // hive 集合對象
  late Box msgBox;

  // 消息列表
  var _msgList = [];

載入所有數(shù)據(jù)

  // 讀取數(shù)據(jù)
  void _loadData() {
    // 倒序
    _msgList = msgBox.values.toList().reversed.toList();
    if (mounted) {
      setState(() {});
    }
  }

初始

  // 初始化
  Future<void> _init() async {
    msgBox = await Hive.openBox('msgBox');
    _loadData();
  }
  @override
  void initState() {
    super.initState();
    _init();
  }

模擬一條數(shù)據(jù)

  // 模擬接收到一條消息
  Map _recvMsg() {
    var newMsg = {
      "message_id": DateTime.now().millisecondsSinceEpoch.toString(),
      "sender": {
        "user_id": "user${generateRandomNumberString()}",
        "username": generateRandomString(),
        "avatar_url": "https://example.com/avatar.jpg"
      },
      "receiver": {
        "user_id": "user002",
        "username": "Bob",
        "avatar_url": "https://example.com/avatar2.jpg"
      },
      "content": "Hello, how are you?",
      "timestamp": "2023-06-24T10:30:00Z",
      "type": "text",
      "status": "sent",
      "read": false
    };
    return newMsg;
  }

按鈕組:新增、所有

  Widget _buildBtns() {
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        // 新增
        ElevatedButton(
          onPressed: () {
            var msg = _recvMsg();
            msgBox.put(msg["message_id"], msg);
            _loadData();
          },
          child: const Text("新增"),
        ),
        const SizedBox(width: 10),
        
        // 所有
        ElevatedButton(
          onPressed: () {
            _loadData();
          },
          child: const Text("所有"),
        ),
      ],
    );
  }

構建列表

  Widget _buildList() {
    return ListView.builder(
      itemCount: _msgList.length,
      itemBuilder: (context, index) {
        var msg = _msgList[index];
        return ListTile(
          title: Text(msg["sender"]["user_id"]),
          subtitle: Text(msg["sender"]["username"]),
        );
      },
    );
  }

主視圖

  Widget _mainView() {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          // 按鈕
          _buildBtns(),

          // 記錄數(shù)
          Text("記錄數(shù): ${_msgList.length}"),

          // 列表
          Expanded(child: _buildList()),
        ],
      ),
    );
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Hive Page'),
      ),
      body: _mainView(),
    );
  }

第三步:刪除

lib/page.dart

  Widget _buildList() {
    return ListView.builder(
      itemCount: _msgList.length,
      itemBuilder: (context, index) {
        var msg = _msgList[index];
        return ListTile(
          title: Text(msg["sender"]["user_id"]),
          subtitle: Text(msg["sender"]["username"]),

          // 刪除按鈕
          trailing: IconButton(
            icon: const Icon(Icons.delete),
            onPressed: () {
              msgBox.delete(msg["message_id"]);
              _loadData();
            },
          ),

        );
      },
    );
  }

最后:查詢

lib/page.dart

  Widget _buildBtns() {
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        // 新增
        ElevatedButton(
          onPressed: () {
            var msg = _recvMsg();
            msgBox.put(msg["message_id"], msg);
            _loadData();
          },
          child: const Text("新增"),
        ),
        const SizedBox(width: 10),

        // 查詢
        ElevatedButton(
          onPressed: () {
            // 查詢 user_id 中含有 8 的用戶
            _msgList = msgBox.values
                .where((element) =>
                    element["sender"]["user_id"]?.indexOf("8") != -1)
                .toList();
            setState(() {});
          },
          child: const Text("包含 8 字符"),
        ),
        const SizedBox(width: 10),

        // 所有
        ElevatedButton(
          onPressed: () {
            _loadData();
          },
          child: const Text("所有"),
        ),
      ],
    );
  }

代碼

https://github.com/ducafecat/flutter_develop_tips/tree/main/flutter_application_hive

小結

Hive 作為一個輕量級俭正、高性能的 NoSQL 數(shù)據(jù)庫,非常適合在 Flutter 應用中用作離線數(shù)據(jù)存儲奸鬓。相比傳統(tǒng)的 SQLite 數(shù)據(jù)庫,Hive 在讀寫性能、跨平臺支持掸读、API 簡單易用等方面都有明顯的優(yōu)勢串远。開發(fā)者可以通過學習本文介紹的 Hive 使用指南,快速將 Hive 數(shù)據(jù)庫集成到 Flutter 項目中,為應用提供穩(wěn)定的離線數(shù)據(jù)支持,提升用戶體驗宏多。

感謝閱讀本文

如果有什么建議,請在評論中讓我知道澡罚。我很樂意改進伸但。


flutter 學習路徑


? 貓哥
ducafecat.com

end

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末留搔,一起剝皮案震驚了整個濱河市更胖,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌催式,老刑警劉巖函喉,帶你破解...
    沈念sama閱讀 216,324評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異荣月,居然都是意外死亡管呵,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評論 3 392
  • 文/潘曉璐 我一進店門哺窄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來捐下,“玉大人,你說我怎么就攤上這事萌业】澜螅” “怎么了?”我有些...
    開封第一講書人閱讀 162,328評論 0 353
  • 文/不壞的土叔 我叫張陵生年,是天一觀的道長婴程。 經(jīng)常有香客問我,道長抱婉,這世上最難降的妖魔是什么档叔? 我笑而不...
    開封第一講書人閱讀 58,147評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮蒸绩,結果婚禮上衙四,老公的妹妹穿的比我還像新娘。我一直安慰自己患亿,他們只是感情好传蹈,可當我...
    茶點故事閱讀 67,160評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著步藕,像睡著了一般惦界。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上咙冗,一...
    開封第一講書人閱讀 51,115評論 1 296
  • 那天表锻,我揣著相機與錄音,去河邊找鬼乞娄。 笑死瞬逊,一個胖子當著我的面吹牛显歧,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播确镊,決...
    沈念sama閱讀 40,025評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼士骤,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了蕾域?” 一聲冷哼從身側響起拷肌,我...
    開封第一講書人閱讀 38,867評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎旨巷,沒想到半個月后巨缘,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,307評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡采呐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,528評論 2 332
  • 正文 我和宋清朗相戀三年若锁,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片斧吐。...
    茶點故事閱讀 39,688評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡又固,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出煤率,到底是詐尸還是另有隱情仰冠,我是刑警寧澤,帶...
    沈念sama閱讀 35,409評論 5 343
  • 正文 年R本政府宣布蝶糯,位于F島的核電站洋只,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏昼捍。R本人自食惡果不足惜识虚,卻給世界環(huán)境...
    茶點故事閱讀 41,001評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望端三。 院中可真熱鬧,春花似錦鹃彻、人聲如沸郊闯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽团赁。三九已至,卻和暖如春谨履,著一層夾襖步出監(jiān)牢的瞬間欢摄,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評論 1 268
  • 我被黑心中介騙來泰國打工笋粟, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留怀挠,地道東北人析蝴。 一個月前我還...
    沈念sama閱讀 47,685評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像绿淋,于是被迫代替她去往敵國和親闷畸。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,573評論 2 353

推薦閱讀更多精彩內(nèi)容