Flutter Hive NoSql 数据库使用指南

news2024/11/24 19:37:01

Flutter Hive NoSql 数据库使用指南

视频

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

https://youtu.be/UJobRKdp68k

前言

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

本文将会写一个 Hive CURD 的例子,详细介绍 Hive 这个轻量级的 Flutter 离线数据库的使用方法,包括 Hive 在 Flutter 开发中的重要性、Hive 与 SQLite 的比较等,帮助开发者快速上手 Hive 数据库。

Flutter, Hive, NoSql, 离线数据库, 键值对数据库, 跨平台开发

参考

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

https://pub.dev/packages/hive

Hive

Hive 是一个 nosql 的离线数据库,在 Flutter 开发中具有重要的作用。以下是 Hive 在 Flutter 开发中的一些重要性:

  • 离线数据存储: Hive 提供了一个高性能的键值对数据库,可以在用户设备上存储大量的离线数据。这对于需要离线使用的应用程序非常有用,例如社交应用、阅读应用等。

  • 快速读写: Hive 基于 Dart 的二进制序列化,读写速度非常快。这对于需要频繁读写数据的应用程序来说非常重要,可以提高用户体验。

  • 跨平台支持: Hive 同时支持 Android 和 iOS 平台,可以在不同操作系统上无缝使用,大大降低了跨平台开发的成本。

  • 简单易用: Hive 的 API 设计得非常简洁明了,上手容易,可以快速集成到 Flutter 项目中。

  • 数据安全: Hive 提供了数据加密功能,可以保护用户的隐私数据安全。

  • 与 Flutter 集成良好: Hive 与 Flutter 集成非常好,可以完美地与 Flutter 的状态管理等其他功能配合使用。

Hive 与 SQLite 比较

  • 数据存储方式:
    • Hive: Hive 是一个基于 Key-Value 的 NoSQL 数据库,数据以二进制形式存储在本地文件中。
    • SQLite: SQLite 是一个基于 SQL 语言的关系型数据库,数据以表格形式存储在本地数据库文件中。
  • 查询方式:
    • Hive: Hive 采用类似 Map 的 API 进行数据的增删改查,比如 get(), put(), delete()等。
    • SQLite: SQLite 采用 SQL 语言进行数据的增删改查,比如 SELECT, INSERT, UPDATE, DELETE等。
  • 性能:
    • Hive: Hive 的读写性能普遍优于 SQLite,因为 Hive 的数据操作更加简单高效。
    • SQLite: SQLite 在处理复杂的查询和关联操作时,性能可能会略优于 Hive。
  • 查询复杂度:
    • Hive: Hive 的查询相对简单,更适合一些基本的数据存储和访问需求。
    • SQLite: SQLite 支持复杂的 SQL 查询,可以处理更加复杂的数据关系和业务需求。
  • 数据库结构:
    • Hive: Hive 的数据结构相对简单,主要是 Key-Value 形式。
    • SQLite: SQLite 支持更加复杂的数据库结构,包括表、索引、视图等。
  • 数据类型:
    • Hive: Hive 支持基本的数据类型,比如 int、string、bool等。
    • SQLite: SQLite 支持更丰富的数据类型,包括 int、float、text、blob等。

Hive 与 shared_preferences 比较

  • Hive

    • NoSQL 数据库

    • 快速高效

    • 支持加密

    • 将数据存储在箱中(类似于表)

    • 支持事务

    • 有更大的存储容量

  • Shared Preferences

    • 键值存储

    • 简单易用

    • 将数据存储在映射中(键值对)

    • 不支持事务

    • 存储容量有限

  • 使用场景:

​ - Hive: 适合大量结构化数据,如用户信息、应用程序设置和游戏数据。

​ - Shared Preferences: 适合少量简单数据,如用户偏好、令牌和标志。

实现步骤

第一步:初始

包依赖 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

工具类,模拟数据用

import 'dart:math';

// 随机字符串函数
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)),
    ),
  );
}
// 随机编号函数
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 = [];

载入所有数据

  // 读取数据
  void _loadData() {
    // 倒序
    _msgList = msgBox.values.toList().reversed.toList();
    if (mounted) {
      setState(() {});
    }
  }

初始

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

模拟一条数据

  // 模拟接收到一条消息
  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(),

          // 记录数
          Text("记录数: ${_msgList.length}"),

          // 列表
          Expanded(child: _buildList()),
        ],
      ),
    );
  }
  
  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 数据库,非常适合在 Flutter 应用中用作离线数据存储。相比传统的 SQLite 数据库,Hive 在读写性能、跨平台支持、API 简单易用等方面都有明显的优势。开发者可以通过学习本文介绍的 Hive 使用指南,快速将 Hive 数据库集成到 Flutter 项目中,为应用提供稳定的离线数据支持,提升用户体验。

感谢阅读本文

如果有什么建议,请在评论中让我知道。我很乐意改进。


flutter 学习路径

  • Flutter 优秀插件推荐 https://flutter.ducafecat.com
  • Flutter 基础篇1 - Dart 语言学习 https://ducafecat.com/course/dart-learn
  • Flutter 基础篇2 - 快速上手 https://ducafecat.com/course/flutter-quickstart-learn
  • Flutter 实战1 - Getx Woo 电商APP https://ducafecat.com/course/flutter-woo
  • Flutter 实战2 - 上架指南 Apple Store、Google Play https://ducafecat.com/course/flutter-upload-apple-google
  • Flutter 基础篇3 - 仿微信朋友圈 https://ducafecat.com/course/flutter-wechat
  • Flutter 实战3 - 腾讯即时通讯 第一篇 https://ducafecat.com/course/flutter-tim
  • Flutter 实战4 - 腾讯即时通讯 第二篇 https://ducafecat.com/course/flutter-tim-s2

© 猫哥
ducafecat.com

end

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1943597.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

解决element-plus的Date Picker日期选择器组件禁用时间的坑

目前需求是有一个表单&#xff0c;其中有多个日期组件需要选择时间范围&#xff0c;并且选择的范围不可以有交集重复&#xff0c;所以这里需要用到Date Picker中的disabled-date属性&#xff0c;来判断该日期是否被禁用。 直接上代码&#xff0c;这个是我写的demo代码&#xf…

基于IEKF迭代扩展卡尔曼滤波算法的数据跟踪matlab仿真,对比EKF和UKF

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于IEKF迭代扩展卡尔曼滤波算法的数据跟踪matlab仿真,对比EKF和UKF.仿真输出误差收敛曲线和误差协方差收敛曲线。 2.测试软件版本以及运行结果展示 MATLAB2022…

社交圈子聊天交友系统搭建社交app开发:陌生交友发布动态圈子单聊打招呼群聊app介绍

系统概述 社交圈子部天交友系统是一个集成即时通讯、社区互动、用户管理等功能的在线社交平台。它支持用户创建个人资料&#xff0c;加入兴趣围子&#xff0c;通过文字、图片、语音、视频等多种方式进行交流&#xff0c;满足用户在不同场景下的社交需求 核心功能 -&#xff0c;…

leetcode日记(46)最后一个单词的长度

很简单&#xff0c;从后往前遍历即可 class Solution { public:int lengthOfLastWord(string s) {int len0;for(int is.size()-1;i>0;i--){if(s[i]! ) len;else if(len!0) break;}return len;} };

Vision Permutator(TPAMI 2022)论文与代码解析

paper&#xff1a;Vision Permutator: A Permutable MLP-Like Architecture for Visual Recognition official implementation&#xff1a;https://github.com/houqb/VisionPermutator 出发点 现有的MLP模型在编码空间信息时通常会将空间维度展开并沿着展平的维度进行线性投…

《Java初阶数据结构》----3.<线性表---LinkedList与链表>

目录 前言 一、链表的简介 1.1链表的概念 1.2链表的八种结构 重点掌握两种 1.3单链表的常见方法 三、单链表的模拟实现 四、LinkedList的模拟实现&#xff08;双链表&#xff09; 4.1 什么是LinkedList 4.2LinkedList的使用 五、ArrayList和LinkedList的区别 前言 …

无法连接到internet怎么办?已连接但无internet访问,其实并不难

有时我们会遇到无法连接到Internet的问题&#xff0c;由多种原因引起&#xff0c;包括硬件故障、软件设置问题、网络供应商故障等。本文将介绍无法连接到Internet时可以采取的步骤。 简述 当你无法连接到Internet时&#xff0c;可以按照以下步骤进行检查和解决&#xff1a; 1…

数据结构C++——优先队列

文章目录 一、定义二、ADT三、优先队列的描述3.1 线性表3.2 堆3.2.1 最大堆的ADT3.2.2 最大堆的插入3.2.3 最大堆的删除3.2.4 最大堆的初始化3.3 左高树 LT3.3.1 高度优先左高树HBLT3.3.2 重量优先左高树WBLT3.3.3 最大HBLT的插入3.3.4 最大HBLT的删除3.3.5 合并两棵最大HBLT3.…

自用:磁传感器数据解算

协议格式&#xff1a; 详细计算磁场如下&#xff1a; 3字节数据的格式为有符号整型数&#xff0c;数据为补码格式&#xff0c;最高位为符号位。需要先将补码格式的数据转化为10进制的实际值&#xff0c;方法如下&#xff1a; 当数据小于时为正数&#xff0c;实际值为本身&…

Mac中maven配置安装路径

Mac中maven配置安装路径 没有下载maven的可以先下载&#xff1a;&#xff08;这里建议maven版本不要下高了&#xff09; 如果你的bash_profile中没有配置JAVA_HOME路径&#xff0c;可以按照下面的命令配置一下 获取JAVA的安装路径&#xff1a; /usr/libexec/java_home -V …

Nest.js 实战 (三):使用 Swagger 优雅地生成 API 文档

什么是 Swagger ? Swagger 是一组围绕 OpenAPI 规范构建的开源工具&#xff0c;可以帮助您设计、构建、记录和使用 REST API。主要的 Swagger 工具 包括&#xff1a; Swagger Editor&#xff1a;基于浏览器的编辑器&#xff0c;您可以在其中编写 OpenAPI 定义Swagger UI&…

NSSCTF[堆][tcache]

1. [CISCN 2021 初赛]lonelywolf 题目地址&#xff1a;[CISCN 2021 初赛]lonelywolf | NSSCTF 思路&#xff1a; 修开tcache结构&#xff0c;伪造一个0x91的chunk&#xff0c;伪造0x91chunk的数量&#xff08;填满tcache&#xff09;&#xff0c;再将其释放free进入unsortedb…

Linux中,MySQL数据库基础

21 世纪&#xff0c;人类迈入了“信息爆炸时代”&#xff0c;大量的数据、信息在不断产生&#xff0c;伴随而来的就是如何安全、有效地存储、检索和管理它们。对数据的有效存储、高效访问、方便共享和安全控制已经成为信息时代亟待解决的问题。 数据库简介 使用数据库的必要性…

MATLAB--文件操作相关指令

文章目录 文件操作相关指令前言 M文件创建MATLAB文件操作指令MATLAB文件流控制 文件操作相关指令 前言 记录一下M文件创建、操作、获取信息等相关资料。   MATLAB的M文件是用来代替MATLAB命令行窗口输入指令的文件。因此所有的MATLAB指令都可以再MATLAB的M文件中调用. M文件…

算法力扣刷题记录 五十七【236. 二叉树的最近公共祖先】和【235. 二叉搜索树的最近公共祖先】

前言 公共祖先解决。二叉树和二叉搜索树条件下的最近公共祖先。 二叉树篇继续。 一、【236. 二叉树的最近公共祖先】题目阅读 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个节点 p、q&#xff…

Spring Bean介绍

目录 1.什么是bean 2.获取bean 3.bean的作用域 4.第三方bean 5.Bean的生命周期 6.Bean的种类 7.为什么使用Bean&#xff1f; 1.什么是bean Bean是Java世界中的一种组件&#xff0c;用于封装数据和逻辑&#xff0c;以便在应用程序中重用和维护。它不仅可以装在数据&#x…

Redis哨兵模式实践

本次环境为Centos7.6&#xff0c;redis-7.0.4 1&#xff1a;主备模式&#xff1a;即主节点的数据自动同步到从节点&#xff0c;但当主节点挂了&#xff0c;从节点需要手动设置为主节点&#xff0c;比较麻烦。 2&#xff1a;哨兵模式&#xff1a;当主节点挂了&#xff0c;自动投…

PCL-基于SAC_IA和NDT结合的点云配准算法

一、原理概述1.点云配准流程图2.快速点特征直方图FPFH3.采样一致性SAC_IA粗配准4.正态分布变换NDT精配准 二、实验代码三、实验结果四、总结五、参考 一、原理概述 1.点云配准流程图 2.快速点特征直方图FPFH 快速点特征直方图&#xff08;Fast Point Feature Histogram&#…

Oracle SQL:了解执行计划和性能调优

查询优化类似于制作完美食谱的艺术——它需要对成分&#xff08;数据&#xff09;、厨房&#xff08;数据库系统&#xff09;和使用的技术&#xff08;查询优化器&#xff09;有深入的了解。每个数据库系统都有自己的处理和运行 SQL 查询的方式&#xff0c;“解释”计划向我们展…

Mysql注意事项(一)

Mysql注意事项&#xff08;一&#xff09; 最近回顾了一下MySQL&#xff0c;发现了一些MySQL需要注意的事项&#xff0c;同时也作为学习笔记&#xff0c;记录下来。–2020年05月13日 1、通配符* 检索所有的列。 不建议使用 通常&#xff0c;除非你确定需要表中的每个列&am…