【Flutter】Flutter Hive 数据库开发 ( 使用 hive、hive_flutter、hive_generator、build_runner 插件开发 Hive 数据库功能 )
参考文档 :
- Flutter 官方文档 : https://docs.flutter.dev/install/quick
- 使用出现网络问题 , 参考 在中国网络环境下使用 Flutter 文档 ;
- 使用 VS Code 开发 Flutter 环境安装 : https://docs.flutter.cn/install/with-vs-code
- VS Code 安装 : https://code.visualstudio.com/docs/setup/setup-overview

前言
在移动应用开发中 , 本地数据持久化 是不可或缺的一环 ;
随着 Flutter 生态的日益成熟 , 开发者面对的选择也越来越多 , 从传统的 SQLite 到轻量级的 键值对存储 ;
Hive 作为一款 纯 Dart 实现、高性能、轻量级的本地数据库 , 因其 无需原生依赖、简单易用、支持加密等特性 , 正受到越来越多 Flutter 开发者的青睐 ;
本文将带你全面了解 Flutter Hive 数据库 : 从技术背景、对比选型 , 到基础用法和生产级实战 , 再到开发中的那些 " 坑 " 和注意事项 , 帮助你快速掌握并在真实项目中稳妥落地 Hive ;
一、Flutter Hive 数据库简介
1、什么是 Hive
Hive 是一款专为 Flutter 和 Dart 设计的轻量级 NoSQL 键值对数据库 , 完全由 Dart 语言编写 , 无需原生依赖 , 不依赖任何移动平台的 SQLite 或 SharedPreferences 实现 , 因此在跨平台一致性、初始化速度上具有天然优势 ;
Flutter Hive 数据库 以 Box ( 盒子 ) 为核心存储单元 , 数据以二进制格式持久化到本地磁盘 , 读写性能远超传统关系型数据库方案 ;
Hive 的设计理念是简单、快速、可靠 , 特别适合存储结构化程度不高、需要频繁读写的本地数据 , 如用户配置、缓存数据、会话信息、离线列表等 ;
Hive 同时支持 基本数据类型 直接存取 , 也支持 通过代码生成或手动适配器存储 自定义对象 ;
2、Hive 的核心优势
Hive 的核心优势 :
- 极致性能 : 纯 Dart 二进制存储 , 内存映射读写 , 速度比 sqflite 高数倍 , 尤其适合小数据量高频读写场景 ;
- 零原生依赖 : 不依赖 SQLite、不调用原生平台 API , 跨平台一致性极强 , 支持 Android、iOS、Web、Windows、macOS、Linux 全平台 ;
- 强类型支持 : 通过 TypeAdapter 支持自定义 Dart 对象存储 , 保留类型安全 , 无需手动 JSON 序列化 ;
- API 简洁 : 类 Map 的操作接口 , put、get、delete 用法直观 , 学习成本极低 ;
- 加密支持 : 内置 AES-256 加密 , 可 直接对敏感数据 Box 进行加密存储 ;
- 异步友好 : 多数操作为同步 API , 无需 async/await , 代码更简洁 ; 同时也支持异步初始化 ;
3、Flutter 常见本地数据库对比
Flutter 生态中主流的本地数据存储方案主要有四类 , 各有适用场景 :
| 对比维度 | Hive | sqflite | Isar | shared_preferences |
|---|---|---|---|---|
| 数据库类型 | NoSQL 键值对 | 关系型 SQL | NoSQL 对象数据库 | 键值对 ( 轻量 ) |
| 底层实现 | 纯 Dart 二进制 | 原生 SQLite | 纯 Dart + C 引擎 | 原生平台偏好设置 |
| 性能 | 极高 | 中等 | 极高 | 一般 |
| 自定义对象 | 支持 ( TypeAdapter ) | 不支持 ( 需手动映射 ) | 支持 ( 注解 ) | 仅基础类型 |
| 复杂查询 | 弱 ( 仅按键查询 ) | 强 ( SQL 语句 ) | 强 ( 索引 + 查询器 ) | 无 |
| 全平台支持 | 全平台 | 移动端为主 | 全平台 | 全平台 |
| 学习成本 | 低 | 中高 | 中等 | 极低 |
| 数据量适配 | 中小规模 | 大规模 | 中大规模 | 极小配置项 |
4、Flutter 各数据库适用场景
Flutter 各数据库适用场景 :
- Hive 适用场景 : 用户偏好设置、会话状态、离线缓存列表、配置项、简单对象集合、需要高频读写的轻量数据 ; 对跨平台一致性要求高、不希望引入原生依赖的项目 ;
- sqflite 适用场景 : 数据关系复杂、需要多表关联、复杂条件查询、大量结构化数据的场景 , 如订单系统、通讯录 ;
- Isar 适用场景 : 数据量较大、需要高性能复杂查询、需要索引和过滤的场景 , 是 Hive 的进阶替代方案 ;
- shared_preferences 适用场景 : 仅存储少量基础类型配置 , 如开关状态、主题色、Token 等极轻量数据 ;
二、Flutter Hive 完整开发流程
1、配置依赖
在 Flutter 项目中使用 Hive , 通常会涉及以下几个核心插件 :
hive: 核心数据库包 , 提供数据库、盒 ( Box ) 、适配器等基础功能 ;hive_flutter: Flutter 专用拓展 , 提供Hive.initFlutter()等便捷方法 , 自动处理路径初始化 ;hive_generator: 代码生成器 , 用于自动生成类型适配器 ( TypeAdapter ) ;build_runner: 配合hive_generator执行代码生成 ;
四个核心插件对比 :
| 插件包 | 作用 | 适用环境 |
|---|---|---|
hive |
Hive 核心库 , 提供基础的数据库操作 API | 生产环境 |
hive_flutter |
Hive 的 Flutter 扩展包 , 提供 Hive.initFlutter() 等平台适配方法 |
Flutter 项目 |
hive_generator |
代码生成器 , 用于自动生成 TypeAdapter ( 类型适配器 ) | 开发环境 ( dev_dependencies ) |
build_runner |
Dart 代码生成构建工具 , 配合 hive_generator 使用 | 开发环境 ( dev_dependencies ) |
pubspec.yaml 示例依赖 :
dependencies:
hive: ^2.2.3
hive_flutter: ^1.1.0
dev_dependencies:
hive_generator: ^2.0.1
build_runner: ^2.4.6
注意 : 两个在 dependencies 中配置 , 这是运行依赖库 , 两个在 dev_dependencies 中配置 , 这是开发依赖库 ;
配置完毕后 , 执行
flutter pub get
命令 , 下载依赖 ;
2、初始化 Hive 数据库
在应用入口 ( main.dart ) 中初始化 Hive , Flutter 项目必须使用 Hive.initFlutter() , 它会自动获取平台正确的文档目录 ;
import 'package:flutter/material.dart';
import 'package:hive_flutter/hive_flutter.dart';
void main() async {
// 确保 WidgetsFlutterBinding 初始化
WidgetsFlutterBinding.ensureInitialized();
// 初始化 Hive
await Hive.initFlutter();
// 注册适配器 ( 自定义对象时需要 , 后文介绍 )
// Hive.registerAdapter(UserAdapter());
// 打开 Box ( 建议提前打开常用 Box )
await Hive.openBox('settings');
runApp(const MyApp());
}
Box 是 Hive 的核心存储单元 , 类似 SQLite 的表或 SharedPreferences 的命名空间 , 可以按业务模块划分多个 Box ;
3、Hive 基础数据操作
Hive 基础数据操作 : Hive 的 Box 操作与 Map 高度相似 , 支持同步读写 ;
- 写入数据 :
final settingsBox = Hive.box('settings');
// 写入基础类型
settingsBox.put('themeMode', 'dark');
settingsBox.put('isFirstLaunch', false);
settingsBox.put('fontSize', 16.0);
// 批量写入
settingsBox.putAll({
'language': 'zh-CN',
'notificationEnabled': true,
});
- 读取数据 :
// 读取数据 , 不存在返回 null
String? theme = settingsBox.get('themeMode');
// 读取并设置默认值
bool isFirst = settingsBox.get('isFirstLaunch', defaultValue: true);
// 读取所有 key
List<dynamic> keys = settingsBox.keys.toList();
- 删除与清空 :
// 删除单个键值
settingsBox.delete('themeMode');
// 检查是否存在
bool hasKey = settingsBox.containsKey('themeMode');
// 清空 Box
await settingsBox.clear();
4、自定义对象存储 TypeAdapter
Hive 支持存储自定义 Dart 对象 , 但需要为每个实体类生成对应的 TypeAdapter ;
- 步骤一 : 定义实体类并添加注解 , 继承 HiveObject 后 , 对象可直接调用 save()、delete() 方法进行自身持久化操作 , 更加便捷 ;
import 'package:hive/hive.dart';
part 'user.g.dart'; // 生成的适配器文件
(typeId: 0) // typeId 范围 0-255 , 每个类唯一
class User extends HiveObject {
(0) // 字段索引 , 修改后不可随意变更
final String id;
(1)
final String username;
(2)
final int age;
(3)
final String? avatar;
User({
required this.id,
required this.username,
required this.age,
this.avatar,
});
}
- 步骤二 : 执行代码生成 , 在项目根目录运行命令 , 执行后会自动生成 user.g.dart 文件 , 其中包含 UserAdapter ;
dart run build_runner build
- 步骤三 : 注册适配器并使用 ;
// 在 main.dart 初始化时注册
Hive.registerAdapter(UserAdapter());
// 打开对象 Box
await Hive.openBox<User>('userBox');
// 存储对象
final userBox = Hive.box<User>('userBox');
final user = User(id: '001', username: '张三', age: 25);
await userBox.put('currentUser', user);
// 读取对象
User? currentUser = userBox.get('currentUser');
5、监听数据变化
Hive 支持监听 Box 的数据变更 , 实现响应式更新 :
// 监听整个 Box 变化
settingsBox.watch().listen((event) {
print('键 ${event.key} 发生变化 , 新值 : ${event.value}');
});
// 监听特定键的变化
settingsBox.watch(key: 'themeMode').listen((event) {
print('主题模式变更为 : ${event.value}');
});
// 在 Widget 中使用 ValueListenableBuilder 响应式刷新
ValueListenableBuilder(
valueListenable: settingsBox.listenable(),
builder: (context, Box box, child) {
return Text('当前主题 : ${box.get('themeMode')}');
},
)
三、生产环境示例 : 封装与工程化
在实际项目中 , 建议对 Hive 进行统一封装 , 实现单例管理、错误捕获、统一初始化、加密支持和业务层解耦 ;
以下是生产级别的完整封装方案 ;
1、数据库管理单例
import 'package:hive_flutter/hive_flutter.dart';
/// Hive 数据库管理类 ( 单例 )
class HiveDbManager {
static final HiveDbManager _instance = HiveDbManager._internal();
factory HiveDbManager() => _instance;
HiveDbManager._internal();
/// 初始化数据库
Future<void> init() async {
await Hive.initFlutter();
_registerAdapters();
await _openAllBoxes();
}
/// 注册所有类型适配器
void _registerAdapters() {
// Hive.registerAdapter(UserEntityAdapter());
// Hive.registerAdapter(ConfigEntityAdapter());
}
/// 预打开所有业务 Box
Future<void> _openAllBoxes() async {
await Future.wait([
Hive.openBox('app_settings'),
// Hive.openBox<UserEntity>('user_box'),
// Hive.openBox<String>('cache_box'),
_openEncryptedBox(), // 加密 Box
]);
}
/// 打开加密 Box ( 存储敏感数据 )
Future<void> _openEncryptedBox() async {
// 生成或读取加密密钥
final encryptionKey = await _getEncryptionKey();
await Hive.openBox(
'secure_box',
encryptionCipher: HiveAesCipher(encryptionKey),
);
}
/// 获取加密密钥 ( 实际项目中可结合 flutter_secure_storage 存储密钥 )
Future<List<int>> _getEncryptionKey() async {
// 示例 : 生成随机密钥 , 生产环境需安全持久化
return Hive.generateSecureKey();
}
/// 快速获取 Box
Box<T> getBox<T>(String boxName) {
return Hive.box<T>(boxName);
}
/// 关闭所有 Box ( 应用退出时调用 )
Future<void> dispose() async {
await Hive.close();
}
}
2、业务层数据仓库封装
/// 用户数据仓库
class UserRepository {
static const String _boxName = 'user_box';
static const String _currentUserKey = 'current_user';
Box<UserEntity> get _box => HiveDbManager().getBox<UserEntity>(_boxName);
/// 保存当前登录用户
Future<void> saveCurrentUser(UserEntity user) async {
await _box.put(_currentUserKey, user);
}
/// 获取当前用户
UserEntity? getCurrentUser() {
return _box.get(_currentUserKey);
}
/// 清除用户信息 ( 退出登录 )
Future<void> clearUser() async {
await _box.delete(_currentUserKey);
}
/// 监听用户信息变化
ValueListenable<Box<UserEntity>> userListenable() {
return _box.listenable(keys: [_currentUserKey]);
}
}
3、在应用中初始化
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// 统一初始化 Hive
await HiveDbManager().init();
runApp(const MyApp());
}
四、开发注意事项与常见坑点
1、核心注意事项
TypeId 与 FieldIndex 不可随意修改
TypeId 与 FieldIndex 不可随意修改 :
@HiveType(typeId: X)的 typeId 范围为 0-255 , 每个实体类必须唯一 , 发布后不可更改 ;@HiveField(X)的 字段索引一旦发布不可随意调换顺序或复用旧索引 , 否则会导致已持久化的数据反序列化异常 ;- 新增字段直接追加新索引即可 , 旧数据读取时会自动填充默认值 null ;
Box 打开时机
Box 打开时机 :
- 频繁使用的 Box 建议在启动时预打开 , 避免使用时重复 openBox 带来的开销 ;
Hive.openBox()是幂等操作 , 已打开的 Box 再次调用会直接返回已有实例 ;
大数据量处理
大数据量处理 :
- Hive 适合中小规模数据 , 单 Box 数据量超过万条且需要复杂查询时 , 建议改用 Isar 或 sqflite ;
- 大量写入操作建议使用 putAll 批量提交 , 减少磁盘 IO 次数 ;
加密数据安全
加密数据安全 :
- 加密 Box 的密钥不能也存储在 Hive 中 , 应使用 flutter_secure_storage 等安全存储方案保管 ;
- 密钥一旦丢失 , 加密 Box 内的数据将无法恢复 ;
2、常见坑点汇总
常见坑点汇总 :
- Web 平台路径问题 : Web 端 Hive 存储在 IndexedDB 中 , Hive.init() 不传路径也可正常工作 , 但必须使用 hive_flutter 包的 initFlutter 方法 ;
- 嵌套对象序列化 : Hive 默认不支持嵌套对象 自动序列化 , 嵌套的自定义类也必须生成对应的 TypeAdapter 并注册 ;
- HiveObject 继承限制 : 继承 HiveObject 的类只能属于一个 Box , 跨 Box 复用会导致 save() 方法异常 ;
- 热重载失效 : 新增或修改 TypeAdapter 后 , 必须重启应用 , 热重载不会重新注册适配器 ;
- List 泛型擦除 : 存储
List<User>时 , Hive 无法自动识别泛型类型 , 需显式注册 List 适配器或手动序列化 ; - 并发写入 : Hive 是单线程 IO , 不支持多 isolate 同时写入 , 跨 isolate 操作需通过消息传递回主线程执行 ;
3、常见报错与解决方案
常见报错与解决方案 :
- 报错一 :
Box not found. Did you forget to call Hive.openBox()?- 原因 : 使用 Hive.box() 时对应 Box 尚未打开 ;
- 解决 : 使用前先调用 await Hive.openBox(name) , 或在启动时统一预打开 ;
- 报错二 :
No adapter found for type XXX- 原因 : 自定义类没有注册 TypeAdapter , 或注册顺序错误 ;
- 解决 : 确保 Hive.registerAdapter() 在打开 Box 之前调用 , 且适配器类已正确生成 ;
- 报错三 :
HiveError: This should not happen.- 原因 : 通常是数据文件损坏或字段索引不匹配导致反序列化失败 ;
- 解决 : 开发阶段可清除应用数据 ; 生产环境需做好版本兼容 , 新增字段使用新索引 ;
- 报错四 :
MissingPluginException- 原因 : 直接使用了
Hive.init()而非Hive.initFlutter(); - 解决 : Flutter 项目统一使用 await Hive.initFlutter() 进行初始化 ;
- 原因 : 直接使用了
总结
本文全面梳理了 Flutter 中 Hive 数据库的开发体系 , 核心知识点可概括如下 :
- 基础认知 : Hive 是纯 Dart 实现的轻量 NoSQL 键值对数据库 , 高性能、全平台、API 简洁 , 适合中小规模本地数据存储 ;
- 生态对比 : 相比 sqflite ( 关系型 ) 、Isar ( 高性能对象库 ) 、shared_preferences ( 极轻量 ) , Hive 在性能与易用性之间取得了良好平衡 , 是中等复杂度本地存储的优选方案 ;
- 开发流程 : 包含依赖引入、initFlutter 初始化、Box 打开、基础类型读写、自定义实体类 TypeAdapter 生成与注册、数据变更监听等完整链路 ;
- 工程实践 : 基础示例展示了快速接入的最小闭环 ; 生产环境示例提供了单例管理、加密 Box、业务仓库层封装等工程化方案 ;
- 避坑指南 : 重点关注
TypeId / FieldIndex的不可变性、嵌套对象序列化、Web 平台适配、加密密钥管理、跨 isolate 限制等问题 , 同时掌握常见报错的排查思路 ;
掌握 Hive 的使用能够显著提升 Flutter 应用本地数据持久化的开发效率与运行性能 , 建议结合项目实际数据规模与查询复杂度 , 合理选择最适配的本地存储方案 ;
更多推荐



所有评论(0)