2026/6/9 23:39:43
网站建设
项目流程
用jsp做网站的技术路线,三合一网站建设用途,网页设计五个页面,吉林3厅官齐聚任免大会宁波网站建设Flutter 本地存储方案#xff1a;SharedPreferences、SQFlite 与 Hive
在 Flutter 应用开发中#xff0c;本地存储是实现数据持久化的核心需求#xff0c;广泛应用于保存用户配置、缓存网络数据、存储离线信息等场景。当前 Flutter 生态中#xff0c;SharedPreferences、S…Flutter 本地存储方案SharedPreferences、SQFlite 与 Hive在 Flutter 应用开发中本地存储是实现数据持久化的核心需求广泛应用于保存用户配置、缓存网络数据、存储离线信息等场景。当前 Flutter 生态中SharedPreferences、SQFlite、Hive 是最主流的三种本地存储方案它们分别基于不同的存储原理适配不同的数据规模与业务场景。本文将从核心原理、实战实现、优缺点分析、横向对比及选型建议五个维度全面解析这三种方案帮助开发者快速选择适配自身项目的本地存储方案。作者爱吃大芒果个人主页 爱吃大芒果本文所属专栏 Flutter更多专栏Ascend C 算子开发教程进阶鸿蒙集成从0到1自学C一、核心原理三种方案的存储本质差异本地存储的核心是将数据持久化到设备本地三种方案的本质差异在于存储载体与数据结构直接决定了其适用场景与性能表现。1. SharedPreferences键值对轻量存储SharedPreferences 是基于平台原生键值对存储的封装在 Android 端封装了SharedPreferences在 iOS 端封装了NSUserDefaults。其核心特点是“轻量、简单”数据以键值对Key-Value形式存储支持字符串、整数、布尔值、浮点数等基础数据类型但不支持复杂对象直接存储。底层存储载体为 XML 文件Android或 plist 文件iOS适合存储少量简单数据。2. SQFlite本地关系型数据库SQFlite 是 SQLite 数据库在 Flutter 中的封装SQLite 是一款嵌入式关系型数据库支持标准 SQL 语法。其核心特点是“结构化、支持复杂查询”数据存储在独立的数据库文件中通过表结构定义数据格式支持多表关联、事务、索引等关系型数据库特性。适合存储大量结构化数据如用户列表、订单记录等。3. HiveNoSQL 文档型数据库Hive 是专为 Flutter 设计的 NoSQL 文档型数据库基于键值对存储但支持复杂对象直接序列化存储。其核心特点是“高性能、跨平台、无依赖”底层采用二进制格式存储数据无需额外的原生依赖纯 Dart 实现支持自定义对象存储通过TypeAdapter实现序列化同时提供了类似 SQL 的查询能力如过滤、排序。兼顾了 SharedPreferences 的简单性与 SQFlite 的数据管理能力适合中大量复杂对象存储。二、实战实现同一需求的三种存储方式以“存储用户信息用户名、年龄、是否登录”为实战需求分别展示三种方案的实现流程与核心代码直观感受其使用差异。1. SharedPreferences 实现轻量键值对存储SharedPreferences 实现需经历“添加依赖→初始化→存储数据→读取数据→删除数据”五个步骤核心代码如下1添加依赖dependencies:flutter:sdk:fluttershared_preferences:^2.2.2# 最新稳定版2核心实现代码importpackage:shared_preferences/shared_preferences.dart;// 封装 SharedPreferences 工具类classSpUtil{// 初始化 SharedPreferences需在使用前调用staticlate SharedPreferences _prefs;staticFuturevoidinit()async{_prefsawaitSharedPreferences.getInstance();}// 存储用户信息基础数据类型staticFuturevoidsaveUserInfo({required String username,required int age,required bool isLogin,})async{await_prefs.setString(username,username);await_prefs.setInt(age,age);await_prefs.setBool(isLogin,isLogin);}// 读取用户信息staticMapString,dynamicgetUserInfo(){return{username:_prefs.getString(username)??,age:_prefs.getInt(age)??0,isLogin:_prefs.getBool(isLogin)??false,};}// 删除单个用户信息staticFuturevoidremoveUserInfo(String key)async{await_prefs.remove(key);}// 清空所有存储数据staticFuturevoidclearAll()async{await_prefs.clear();}}// 调用示例voidmain()async{// 必须先初始化awaitSpUtil.init();// 存储用户信息awaitSpUtil.saveUserInfo(username:FlutterDeveloper,age:25,isLogin:true,);// 读取用户信息finaluserInfoSpUtil.getUserInfo();print(用户名${userInfo[username]}年龄${userInfo[age]}登录状态${userInfo[isLogin]});// 删除单个数据awaitSpUtil.removeUserInfo(age);// 清空所有数据// await SpUtil.clearAll();}核心特点API 简洁直观无需关注底层实现适合存储少量基础类型数据。但不支持复杂对象直接存储需手动将对象转换为基础类型如 JSON 字符串。2. SQFlite 实现结构化数据库存储SQFlite 实现需经历“添加依赖→创建数据库与表→CRUD 操作→关闭数据库”五个步骤核心代码如下1添加依赖dependencies:flutter:sdk:fluttersqflite:^2.3.0# 核心依赖path:^1.8.3# 用于获取数据库文件路径2核心实现代码importpackage:sqflite/sqflite.dart;importpackage:path/path.dart;// 定义用户模型classUser{finalString username;finalint age;finalbool isLogin;User({requiredthis.username,requiredthis.age,requiredthis.isLogin,});// 转换为 Map用于存储MapString,dynamictoMap(){return{username:username,age:age,isLogin:isLogin?1:0,// SQLite 不支持布尔值用 0/1 替代};}// 从 Map 转换为 User用于读取staticUserfromMap(MapString,dynamicmap){returnUser(username:map[username],age:map[age],isLogin:map[isLogin]1,);}}// 封装 SQFlite 工具类classDbUtil{staticlate Database _database;staticconstString dbNameuser_db.db;// 数据库名staticconstString tableNameuser;// 表名// 初始化数据库staticFuturevoidinit()async{// 获取数据库存储路径String dbPathawaitgetDatabasesPath();String pathjoin(dbPath,dbName);// 打开数据库不存在则创建_databaseawaitopenDatabase(path,version:1,// 数据库版本onCreate:(db,version){// 创建表结构db.execute( CREATE TABLE $tableName ( username TEXT PRIMARY KEY, age INTEGER, isLogin INTEGER ) );},);}// 插入用户信息新增/更新staticFuturevoidinsertUser(User user)async{await_database.insert(tableName,user.toMap(),conflictAlgorithm:ConflictAlgorithm.replace,// 存在则替换);}// 查询所有用户信息staticFutureListUserqueryAllUsers()async{finalListMapString,dynamicmapsawait_database.query(tableName);returnList.generate(maps.length,(i)User.fromMap(maps[i]));}// 根据用户名查询用户staticFutureUser?queryUserByUsername(String username)async{finalListMapString,dynamicmapsawait_database.query(tableName,where:username ?,whereArgs:[username],// 防止 SQL 注入);returnmaps.isNotEmpty?User.fromMap(maps.first):null;}// 删除用户staticFuturevoiddeleteUser(String username)async{await_database.delete(tableName,where:username ?,whereArgs:[username],);}// 关闭数据库staticFuturevoidcloseDb()async{await_database.close();}}// 调用示例voidmain()async{// 初始化数据库awaitDbUtil.init();// 插入用户信息finaluserUser(username:FlutterDeveloper,age:25,isLogin:true,);awaitDbUtil.insertUser(user);// 查询所有用户finalallUsersawaitDbUtil.queryAllUsers();print(所有用户${allUsers.map((u) u.username).toList()});// 根据用户名查询finalqueryUserawaitDbUtil.queryUserByUsername(FlutterDeveloper);if(queryUser!null){print(查询用户${queryUser.username}年龄${queryUser.age});}// 删除用户awaitDbUtil.deleteUser(FlutterDeveloper);// 关闭数据库一般在应用退出时调用// await DbUtil.closeDb();}核心特点支持结构化数据存储与复杂查询适合大量数据管理。但需手动设计表结构处理数据类型转换如布尔值SQL 语法有一定学习成本。3. Hive 实现高性能复杂对象存储Hive 实现需经历“添加依赖→初始化→注册适配器→存储数据→读取数据”五个步骤核心代码如下1添加依赖dependencies:flutter:sdk:flutterhive:^2.2.3# 核心依赖hive_flutter:^1.1.0# Flutter 适配依赖提供路径管理等dev_dependencies:hive_generator:^1.1.5# 代码生成工具build_runner:^2.4.4# 代码生成工具2核心实现代码importpackage:hive/hive.dart;importpackage:hive_flutter/hive_flutter.dart;// 1. 定义用户模型添加 HiveType 注解partuser.g.dart;// 生成的适配器文件HiveType(typeId:0)// typeId 为唯一标识0-223classUser{HiveField(0)// 字段标识唯一finalString username;HiveField(1)finalint age;HiveField(2)finalbool isLogin;User({requiredthis.username,requiredthis.age,requiredthis.isLogin,});}// 2. 生成适配器执行命令flutter pub run build_runner build// 生成后会自动创建 user.g.dart 文件// 3. 封装 Hive 工具类classHiveUtil{staticlate BoxUser_userBox;staticconstString boxNameuser_box;// 盒子名Hive 中数据存储在盒子里// 初始化 HivestaticFuturevoidinit()async{awaitHive.initFlutter();// 初始化 Flutter 适配Hive.registerAdapter(UserAdapter());// 注册适配器必须_userBoxawaitHive.openBoxUser(boxName);// 打开盒子}// 存储用户信息key 为用户名value 为 User 对象staticvoidputUser(String key,User user){_userBox.put(key,user);}// 根据 key 读取用户信息staticUser?getUser(String key){return_userBox.get(key);}// 读取所有用户信息staticMapString,UsergetAllUsers(){return_userBox.toMap().castString,User();}// 删除用户信息staticvoiddeleteUser(String key){_userBox.delete(key);}// 清空盒子staticFuturevoidclearBox()async{await_userBox.clear();}// 关闭 HivestaticFuturevoidcloseHive()async{awaitHive.close();}}// 调用示例voidmain()async{// 初始化 HiveawaitHiveUtil.init();// 存储用户信息finaluserUser(username:FlutterDeveloper,age:25,isLogin:true,);HiveUtil.putUser(FlutterDeveloper,user);// 读取用户信息finalqueryUserHiveUtil.getUser(FlutterDeveloper);if(queryUser!null){print(用户名${queryUser.username}年龄${queryUser.age}登录状态${queryUser.isLogin});}// 读取所有用户finalallUsersHiveUtil.getAllUsers();print(所有用户${allUsers.keys.toList()});// 删除用户HiveUtil.deleteUser(FlutterDeveloper);// 清空盒子// await HiveUtil.clearBox();// 关闭 Hive// await HiveUtil.closeHive();}核心特点支持复杂对象直接存储无需手动转换API 简洁性能优异纯 Dart 实现无原生依赖。需通过代码生成工具创建适配器适配复杂对象存储。三、优缺点深度分析适配场景决定选型结合实战体验从数据类型、性能、易用性、扩展性等维度深度剖析三种方案的优缺点明确其适用边界。1. SharedPreferences 优缺点优点① 易用性极高API 简洁直观开发成本低② 轻量级无额外依赖集成简单③ 跨平台适配良好底层基于原生实现稳定性高④ 适合存储少量配置信息如登录状态、主题设置。缺点① 仅支持基础数据类型不支持复杂对象直接存储② 性能较差大量数据存储时读取速度慢③ 无事务支持数据一致性难以保证④ 不支持复杂查询仅能通过键获取值。2. SQFlite 优缺点优点① 支持结构化数据存储表结构清晰适合大量数据管理② 支持标准 SQL 语法可实现复杂查询多条件过滤、排序、关联查询等③ 支持事务保证数据一致性④ 稳定性高适配所有 Flutter 支持的平台。缺点① 易用性较差需手动设计表结构、处理数据类型转换② SQL 语法有一定学习成本开发效率低③ 复杂对象存储需手动序列化/反序列化④ 性能一般大量数据读写时效率低于 Hive。3. Hive 优缺点优点① 性能优异底层二进制存储读写速度快于 SQFlite② 支持复杂对象直接存储通过适配器实现自动化序列化③ 纯 Dart 实现无原生依赖跨平台适配更简单④ API 简洁直观兼顾易用性与扩展性⑤ 支持事务、索引、查询过滤等高级特性。缺点① 复杂对象存储需通过代码生成工具创建适配器额外增加配置步骤② 生态相对 SQFlite 较新部分边缘场景支持不足③ 不支持 SQL 语法复杂查询需通过 Hive 自带 API 实现灵活性低于 SQFlite。四、横向对比一张表看懂核心差异对比维度SharedPreferencesSQFliteHive存储类型键值对基础类型关系型数据库结构化NoSQL 文档型键值对复杂对象支持数据类型字符串、整数、布尔值、浮点数、列表文本、整数、浮点数、 blob 等需手动转换布尔值所有 Dart 基础类型自定义对象易用性★★★★★极高★★☆较低★★★★较高性能大量数据★☆较差★★★一般★★★★★极佳复杂查询支持无★★★★★SQL 语法灵活★★★自带 API有限灵活事务支持无有有跨平台依赖依赖原生实现依赖原生 SQLite纯 Dart无依赖适用数据规模少量KB 级大量MB/GB 级中大量MB 级扩展能力差强SQL 扩展强自定义适配器五、实战选型建议匹配项目与业务需求本地存储方案的选型需结合数据规模、数据类型、查询需求、开发效率四大核心因素以下是针对性建议1. 优先选 SharedPreferences 的场景① 存储少量配置信息如登录状态、主题模式、语言设置、用户 Token② 数据类型简单仅基础类型无需复杂查询③ 追求极致开发效率无需额外配置④ 小型工具类 App 或 MVP 原型验证。2. 优先选 SQFlite 的场景① 存储大量结构化数据如用户列表、订单记录、离线缓存的商品数据② 需要复杂查询如多条件过滤、排序、分组、多表关联③ 对数据一致性要求高需要事务支持④ 团队熟悉 SQL 语法可接受较高的开发成本。3. 优先选 Hive 的场景① 存储中大量复杂对象如自定义模型、嵌套数据结构② 追求高性能读写对响应速度要求高③ 跨平台适配需求严格如需要适配 Web 端避免原生依赖④ 兼顾易用性与扩展性既不想写 SQL又需要比 SharedPreferences 更强的功能。4. 混合使用建议大型项目可采用“主方案辅助方案”的混合模式① 用 SharedPreferences 存储配置信息如登录状态、Token② 用 SQFlite 或 Hive 存储核心业务数据如用户信息、订单列表。例如电商 App 中用 SharedPreferences 保存用户登录状态用 Hive 存储离线商品缓存用 SQFlite 存储复杂的订单历史数据。六、注意事项与最佳实践无论选择哪种存储方案都需注意以下核心要点提升数据存储的稳定性与安全性数据加密敏感数据如用户密码、Token需加密后存储可使用encrypt库实现 AES 加密初始化时机所有存储方案的初始化都需在异步中完成建议在main函数中初始化确保使用前已完成资源释放SQFlite 与 Hive 需在应用退出时关闭避免资源泄漏数据迁移SQFlite 需妥善处理数据库版本升级与表结构迁移Hive 需处理适配器版本兼容性能优化① SharedPreferences 避免频繁读写大量数据② SQFlite 合理创建索引提升查询速度③ Hive 避免在主线程进行大量数据读写可使用compute进行异步处理。七、结语SharedPreferences、SQFlite、Hive 三种本地存储方案无绝对优劣核心差异在于适配场景SharedPreferences 胜在“简单、轻量”适合少量配置SQFlite 胜在“结构化、强查询”适合大量复杂数据Hive 胜在“高性能、跨平台、支持复杂对象”兼顾易用性与扩展性。开发者在选型时应跳出“技术优劣”的误区聚焦业务需求明确数据规模、数据类型、查询复杂度结合团队技术栈选择最能降低开发成本、提升应用性能的方案。同时合理运用混合存储模式可最大化发挥各方案的优势构建稳定、高效的本地存储体系。